
bin/kernel:     file format elf32-i386


Disassembly of section .text:

c0100000 <kern_entry>:

.text
.globl kern_entry
kern_entry:
    # load pa of boot pgdir
    movl $REALLOC(__boot_pgdir), %eax
c0100000:	b8 00 10 1a 00       	mov    $0x1a1000,%eax
    movl %eax, %cr3
c0100005:	0f 22 d8             	mov    %eax,%cr3

    # enable paging
    movl %cr0, %eax
c0100008:	0f 20 c0             	mov    %cr0,%eax
    orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP), %eax
c010000b:	0d 2f 00 05 80       	or     $0x8005002f,%eax
    andl $~(CR0_TS | CR0_EM), %eax
c0100010:	83 e0 f3             	and    $0xfffffff3,%eax
    movl %eax, %cr0
c0100013:	0f 22 c0             	mov    %eax,%cr0

    # update eip
    # now, eip = 0x1.....
    leal next, %eax
c0100016:	8d 05 1e 00 10 c0    	lea    0xc010001e,%eax
    # set eip = KERNBASE + 0x1.....
    jmp *%eax
c010001c:	ff e0                	jmp    *%eax

c010001e <next>:
next:

    # unmap va 0 ~ 4M, it's temporary mapping
    xorl %eax, %eax
c010001e:	31 c0                	xor    %eax,%eax
    movl %eax, __boot_pgdir
c0100020:	a3 00 10 1a c0       	mov    %eax,0xc01a1000

    # set ebp, esp
    movl $0x0, %ebp
c0100025:	bd 00 00 00 00       	mov    $0x0,%ebp
    # the kernel stack region is from bootstack -- bootstacktop,
    # the kernel stack size is KSTACKSIZE (8KB)defined in memlayout.h
    movl $bootstacktop, %esp
c010002a:	bc 00 f0 12 c0       	mov    $0xc012f000,%esp
    # now kernel stack is ready , call the first C function
    call kern_init
c010002f:	e8 02 00 00 00       	call   c0100036 <kern_init>

c0100034 <spin>:

# should never get here
spin:
    jmp spin
c0100034:	eb fe                	jmp    c0100034 <spin>

c0100036 <kern_init>:
void grade_backtrace(void);
static void lab1_switch_test(void);


    int
kern_init(void) {
c0100036:	55                   	push   %ebp
c0100037:	89 e5                	mov    %esp,%ebp
c0100039:	83 ec 28             	sub    $0x28,%esp
    extern char edata[], end[]; //声明外部变量 edata 和 end
    memset(edata, 0, end - edata); // 将数据段清零
c010003c:	b8 54 61 1a c0       	mov    $0xc01a6154,%eax
c0100041:	2d 00 30 1a c0       	sub    $0xc01a3000,%eax
c0100046:	89 44 24 08          	mov    %eax,0x8(%esp)
c010004a:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0100051:	00 
c0100052:	c7 04 24 00 30 1a c0 	movl   $0xc01a3000,(%esp)
c0100059:	e8 93 bd 00 00       	call   c010bdf1 <memset>

    cons_init();                // init the console 初始化控制台
c010005e:	e8 4a 16 00 00       	call   c01016ad <cons_init>

    const char *message = "(THU.CST) os is loading ...";
c0100063:	c7 45 f4 80 bf 10 c0 	movl   $0xc010bf80,-0xc(%ebp)
    cprintf("%s\n\n", message);// 将消息输出到控制台
c010006a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010006d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100071:	c7 04 24 9c bf 10 c0 	movl   $0xc010bf9c,(%esp)
c0100078:	e8 fb 02 00 00       	call   c0100378 <cprintf>

    print_kerninfo();// 输出内核信息的函数
c010007d:	e8 0f 09 00 00       	call   c0100991 <print_kerninfo>

    grade_backtrace(); //调用回溯函数，通常用于调试，显示函数调用栈。
c0100082:	e8 a7 00 00 00       	call   c010012e <grade_backtrace>

    pmm_init();                 // init physical memory management初始化物理内存管理
c0100087:	e8 c3 56 00 00       	call   c010574f <pmm_init>

    pic_init();                 // init interrupt controller初始化可编程中断控制器
c010008c:	e8 fa 1f 00 00       	call   c010208b <pic_init>
    idt_init();                 // init interrupt descriptor table初始化中断描述符表
c0100091:	e8 5e 21 00 00       	call   c01021f4 <idt_init>

    vmm_init();                 // init virtual memory management 初始化虚拟内存管理
c0100096:	e8 95 86 00 00       	call   c0108730 <vmm_init>
    
    proc_init();                // init process table
c010009b:	e8 02 ad 00 00       	call   c010ada2 <proc_init>

    ide_init();                 // init ide devices初始化IDE设备
c01000a0:	e8 42 17 00 00       	call   c01017e7 <ide_init>
    swap_init();                // init swap 初始化交换分区
c01000a5:	e8 5d 6d 00 00       	call   c0106e07 <swap_init>

    clock_init();               // init clock interrupt 初始化时钟中断
c01000aa:	e8 5d 0d 00 00       	call   c0100e0c <clock_init>
    intr_enable();              // enable irq interrupt
c01000af:	e8 35 1f 00 00       	call   c0101fe9 <intr_enable>

    //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test()
    // user/kernel mode switch test
    //lab1_switch_test();
    
    cpu_idle();                 // run idle process 运行空闲进程
c01000b4:	e8 aa ae 00 00       	call   c010af63 <cpu_idle>

c01000b9 <grade_backtrace2>:
}

//不进行内联的回溯函数，调用 mon_backtrace 显示当前的调用栈。
void __attribute__((noinline))
grade_backtrace2(int arg0, int arg1, int arg2, int arg3) {
c01000b9:	55                   	push   %ebp
c01000ba:	89 e5                	mov    %esp,%ebp
c01000bc:	83 ec 18             	sub    $0x18,%esp
    mon_backtrace(0, NULL, NULL);
c01000bf:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01000c6:	00 
c01000c7:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01000ce:	00 
c01000cf:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c01000d6:	e8 4c 0c 00 00       	call   c0100d27 <mon_backtrace>
}
c01000db:	90                   	nop
c01000dc:	89 ec                	mov    %ebp,%esp
c01000de:	5d                   	pop    %ebp
c01000df:	c3                   	ret    

c01000e0 <grade_backtrace1>:
//不进行内联的回溯函数，传递参数到 grade_backtrace2
void __attribute__((noinline))
grade_backtrace1(int arg0, int arg1) {
c01000e0:	55                   	push   %ebp
c01000e1:	89 e5                	mov    %esp,%ebp
c01000e3:	83 ec 18             	sub    $0x18,%esp
c01000e6:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1);
c01000e9:	8d 4d 0c             	lea    0xc(%ebp),%ecx
c01000ec:	8b 55 0c             	mov    0xc(%ebp),%edx
c01000ef:	8d 5d 08             	lea    0x8(%ebp),%ebx
c01000f2:	8b 45 08             	mov    0x8(%ebp),%eax
c01000f5:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c01000f9:	89 54 24 08          	mov    %edx,0x8(%esp)
c01000fd:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c0100101:	89 04 24             	mov    %eax,(%esp)
c0100104:	e8 b0 ff ff ff       	call   c01000b9 <grade_backtrace2>
}
c0100109:	90                   	nop
c010010a:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c010010d:	89 ec                	mov    %ebp,%esp
c010010f:	5d                   	pop    %ebp
c0100110:	c3                   	ret    

c0100111 <grade_backtrace0>:
//不进行内联的回溯函数，传递参数到 grade_backtrace1
void __attribute__((noinline))
grade_backtrace0(int arg0, int arg1, int arg2) {
c0100111:	55                   	push   %ebp
c0100112:	89 e5                	mov    %esp,%ebp
c0100114:	83 ec 18             	sub    $0x18,%esp
    grade_backtrace1(arg0, arg2);
c0100117:	8b 45 10             	mov    0x10(%ebp),%eax
c010011a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010011e:	8b 45 08             	mov    0x8(%ebp),%eax
c0100121:	89 04 24             	mov    %eax,(%esp)
c0100124:	e8 b7 ff ff ff       	call   c01000e0 <grade_backtrace1>
}
c0100129:	90                   	nop
c010012a:	89 ec                	mov    %ebp,%esp
c010012c:	5d                   	pop    %ebp
c010012d:	c3                   	ret    

c010012e <grade_backtrace>:
//触发回溯的起始点，传递初始化函数地址。
void
grade_backtrace(void) {
c010012e:	55                   	push   %ebp
c010012f:	89 e5                	mov    %esp,%ebp
c0100131:	83 ec 18             	sub    $0x18,%esp
    grade_backtrace0(0, (int)kern_init, 0xffff0000);
c0100134:	b8 36 00 10 c0       	mov    $0xc0100036,%eax
c0100139:	c7 44 24 08 00 00 ff 	movl   $0xffff0000,0x8(%esp)
c0100140:	ff 
c0100141:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100145:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c010014c:	e8 c0 ff ff ff       	call   c0100111 <grade_backtrace0>
}
c0100151:	90                   	nop
c0100152:	89 ec                	mov    %ebp,%esp
c0100154:	5d                   	pop    %ebp
c0100155:	c3                   	ret    

c0100156 <lab1_print_cur_status>:
//打印当前的段寄存器状态。
static void
lab1_print_cur_status(void) {
c0100156:	55                   	push   %ebp
c0100157:	89 e5                	mov    %esp,%ebp
c0100159:	83 ec 28             	sub    $0x28,%esp
    static int round = 0;
    uint16_t reg1, reg2, reg3, reg4;
    //嵌入汇编代码，确保编译器不优化这些代码。
    asm volatile (
c010015c:	8c 4d f6             	mov    %cs,-0xa(%ebp)
c010015f:	8c 5d f4             	mov    %ds,-0xc(%ebp)
c0100162:	8c 45 f2             	mov    %es,-0xe(%ebp)
c0100165:	8c 55 f0             	mov    %ss,-0x10(%ebp)
            "mov %%cs, %0;"// 将当前代码段寄存器的值移动到 reg1
            "mov %%ds, %1;"
            "mov %%es, %2;"
            "mov %%ss, %3;"
            : "=m"(reg1), "=m"(reg2), "=m"(reg3), "=m"(reg4));
    cprintf("%d: @ring %d\n", round, reg1 & 3);//打印当前的 round、权限级（ring）和各段寄存器的值。
c0100168:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010016c:	83 e0 03             	and    $0x3,%eax
c010016f:	89 c2                	mov    %eax,%edx
c0100171:	a1 00 30 1a c0       	mov    0xc01a3000,%eax
c0100176:	89 54 24 08          	mov    %edx,0x8(%esp)
c010017a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010017e:	c7 04 24 a1 bf 10 c0 	movl   $0xc010bfa1,(%esp)
c0100185:	e8 ee 01 00 00       	call   c0100378 <cprintf>
    cprintf("%d:  cs = %x\n", round, reg1);
c010018a:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010018e:	89 c2                	mov    %eax,%edx
c0100190:	a1 00 30 1a c0       	mov    0xc01a3000,%eax
c0100195:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100199:	89 44 24 04          	mov    %eax,0x4(%esp)
c010019d:	c7 04 24 af bf 10 c0 	movl   $0xc010bfaf,(%esp)
c01001a4:	e8 cf 01 00 00       	call   c0100378 <cprintf>
    cprintf("%d:  ds = %x\n", round, reg2);
c01001a9:	0f b7 45 f4          	movzwl -0xc(%ebp),%eax
c01001ad:	89 c2                	mov    %eax,%edx
c01001af:	a1 00 30 1a c0       	mov    0xc01a3000,%eax
c01001b4:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001b8:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001bc:	c7 04 24 bd bf 10 c0 	movl   $0xc010bfbd,(%esp)
c01001c3:	e8 b0 01 00 00       	call   c0100378 <cprintf>
    cprintf("%d:  es = %x\n", round, reg3);
c01001c8:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c01001cc:	89 c2                	mov    %eax,%edx
c01001ce:	a1 00 30 1a c0       	mov    0xc01a3000,%eax
c01001d3:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001d7:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001db:	c7 04 24 cb bf 10 c0 	movl   $0xc010bfcb,(%esp)
c01001e2:	e8 91 01 00 00       	call   c0100378 <cprintf>
    cprintf("%d:  ss = %x\n", round, reg4);
c01001e7:	0f b7 45 f0          	movzwl -0x10(%ebp),%eax
c01001eb:	89 c2                	mov    %eax,%edx
c01001ed:	a1 00 30 1a c0       	mov    0xc01a3000,%eax
c01001f2:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001f6:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001fa:	c7 04 24 d9 bf 10 c0 	movl   $0xc010bfd9,(%esp)
c0100201:	e8 72 01 00 00       	call   c0100378 <cprintf>
    round ++;//将 round 增加1，以便每次调用时记录状态。
c0100206:	a1 00 30 1a c0       	mov    0xc01a3000,%eax
c010020b:	40                   	inc    %eax
c010020c:	a3 00 30 1a c0       	mov    %eax,0xc01a3000
}
c0100211:	90                   	nop
c0100212:	89 ec                	mov    %ebp,%esp
c0100214:	5d                   	pop    %ebp
c0100215:	c3                   	ret    

c0100216 <lab1_switch_to_user>:

static void
lab1_switch_to_user(void) {
c0100216:	55                   	push   %ebp
c0100217:	89 e5                	mov    %esp,%ebp
    // 从内核模式切换到用户模式
    //LAB1 CHALLENGE 1 : TODO
    asm volatile (
c0100219:	83 ec 08             	sub    $0x8,%esp
c010021c:	cd 78                	int    $0x78
c010021e:	89 ec                	mov    %ebp,%esp
	    "int %0 \n"//通过触发一个中断，将控制权转移到内核，切换到用户模式。
	    "movl %%ebp, %%esp"// 将基指针（EBP）值移动到堆栈指针（ESP），恢复堆栈指针。
	    : 
	    : "i"(T_SWITCH_TOU)//T_SWITCH_TOU是一个常量，表示切换到用户态的中断号。传入常量 T_SWITCH_TOU
	);
}
c0100220:	90                   	nop
c0100221:	5d                   	pop    %ebp
c0100222:	c3                   	ret    

c0100223 <lab1_switch_to_kernel>:

static void
lab1_switch_to_kernel(void) {
c0100223:	55                   	push   %ebp
c0100224:	89 e5                	mov    %esp,%ebp
    // 从用户模式切换到内核模式
    //LAB1 CHALLENGE 1 :  TODO
    asm volatile (
c0100226:	cd 79                	int    $0x79
c0100228:	89 ec                	mov    %ebp,%esp
	    "int %0 \n"// 同样触发中断，这里用的是 T_SWITCH_TOK，从用户态切换回内核态。
	    "movl %%ebp, %%esp \n"//恢复堆栈指针
	    : 
	    : "i"(T_SWITCH_TOK)//传入常量 T_SWITCH_TOU
	);
}
c010022a:	90                   	nop
c010022b:	5d                   	pop    %ebp
c010022c:	c3                   	ret    

c010022d <lab1_switch_test>:

//测试用户模式和内核模式切换。
//调用 lab1_print_cur_status 打印当前状态，进行模式切换，然后再次打印状态。
static void
lab1_switch_test(void) {
c010022d:	55                   	push   %ebp
c010022e:	89 e5                	mov    %esp,%ebp
c0100230:	83 ec 18             	sub    $0x18,%esp
    lab1_print_cur_status();
c0100233:	e8 1e ff ff ff       	call   c0100156 <lab1_print_cur_status>
    cprintf("+++ switch to  user  mode +++\n");
c0100238:	c7 04 24 e8 bf 10 c0 	movl   $0xc010bfe8,(%esp)
c010023f:	e8 34 01 00 00       	call   c0100378 <cprintf>
    lab1_switch_to_user();
c0100244:	e8 cd ff ff ff       	call   c0100216 <lab1_switch_to_user>
    lab1_print_cur_status();
c0100249:	e8 08 ff ff ff       	call   c0100156 <lab1_print_cur_status>
    cprintf("+++ switch to kernel mode +++\n");
c010024e:	c7 04 24 08 c0 10 c0 	movl   $0xc010c008,(%esp)
c0100255:	e8 1e 01 00 00       	call   c0100378 <cprintf>
    lab1_switch_to_kernel();
c010025a:	e8 c4 ff ff ff       	call   c0100223 <lab1_switch_to_kernel>
    lab1_print_cur_status();
c010025f:	e8 f2 fe ff ff       	call   c0100156 <lab1_print_cur_status>
c0100264:	90                   	nop
c0100265:	89 ec                	mov    %ebp,%esp
c0100267:	5d                   	pop    %ebp
c0100268:	c3                   	ret    

c0100269 <readline>:
 * The readline() function returns the text of the line read. If some errors
 * are happened, NULL is returned. The return value is a global variable,
 * thus it should be copied before it is used.
 * */
char *
readline(const char *prompt) {
c0100269:	55                   	push   %ebp
c010026a:	89 e5                	mov    %esp,%ebp
c010026c:	83 ec 28             	sub    $0x28,%esp
    if (prompt != NULL) {
c010026f:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0100273:	74 13                	je     c0100288 <readline+0x1f>
        cprintf("%s", prompt);
c0100275:	8b 45 08             	mov    0x8(%ebp),%eax
c0100278:	89 44 24 04          	mov    %eax,0x4(%esp)
c010027c:	c7 04 24 27 c0 10 c0 	movl   $0xc010c027,(%esp)
c0100283:	e8 f0 00 00 00       	call   c0100378 <cprintf>
    }
    int i = 0, c;
c0100288:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    while (1) {
        c = getchar();
c010028f:	e8 73 01 00 00       	call   c0100407 <getchar>
c0100294:	89 45 f0             	mov    %eax,-0x10(%ebp)
        if (c < 0) {
c0100297:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010029b:	79 07                	jns    c01002a4 <readline+0x3b>
            return NULL;
c010029d:	b8 00 00 00 00       	mov    $0x0,%eax
c01002a2:	eb 78                	jmp    c010031c <readline+0xb3>
        }
        else if (c >= ' ' && i < BUFSIZE - 1) {
c01002a4:	83 7d f0 1f          	cmpl   $0x1f,-0x10(%ebp)
c01002a8:	7e 28                	jle    c01002d2 <readline+0x69>
c01002aa:	81 7d f4 fe 03 00 00 	cmpl   $0x3fe,-0xc(%ebp)
c01002b1:	7f 1f                	jg     c01002d2 <readline+0x69>
            cputchar(c);
c01002b3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01002b6:	89 04 24             	mov    %eax,(%esp)
c01002b9:	e8 e2 00 00 00       	call   c01003a0 <cputchar>
            buf[i ++] = c;
c01002be:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01002c1:	8d 50 01             	lea    0x1(%eax),%edx
c01002c4:	89 55 f4             	mov    %edx,-0xc(%ebp)
c01002c7:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01002ca:	88 90 20 30 1a c0    	mov    %dl,-0x3fe5cfe0(%eax)
c01002d0:	eb 45                	jmp    c0100317 <readline+0xae>
        }
        else if (c == '\b' && i > 0) {
c01002d2:	83 7d f0 08          	cmpl   $0x8,-0x10(%ebp)
c01002d6:	75 16                	jne    c01002ee <readline+0x85>
c01002d8:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01002dc:	7e 10                	jle    c01002ee <readline+0x85>
            cputchar(c);
c01002de:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01002e1:	89 04 24             	mov    %eax,(%esp)
c01002e4:	e8 b7 00 00 00       	call   c01003a0 <cputchar>
            i --;
c01002e9:	ff 4d f4             	decl   -0xc(%ebp)
c01002ec:	eb 29                	jmp    c0100317 <readline+0xae>
        }
        else if (c == '\n' || c == '\r') {
c01002ee:	83 7d f0 0a          	cmpl   $0xa,-0x10(%ebp)
c01002f2:	74 06                	je     c01002fa <readline+0x91>
c01002f4:	83 7d f0 0d          	cmpl   $0xd,-0x10(%ebp)
c01002f8:	75 95                	jne    c010028f <readline+0x26>
            cputchar(c);
c01002fa:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01002fd:	89 04 24             	mov    %eax,(%esp)
c0100300:	e8 9b 00 00 00       	call   c01003a0 <cputchar>
            buf[i] = '\0';
c0100305:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100308:	05 20 30 1a c0       	add    $0xc01a3020,%eax
c010030d:	c6 00 00             	movb   $0x0,(%eax)
            return buf;
c0100310:	b8 20 30 1a c0       	mov    $0xc01a3020,%eax
c0100315:	eb 05                	jmp    c010031c <readline+0xb3>
        c = getchar();
c0100317:	e9 73 ff ff ff       	jmp    c010028f <readline+0x26>
        }
    }
}
c010031c:	89 ec                	mov    %ebp,%esp
c010031e:	5d                   	pop    %ebp
c010031f:	c3                   	ret    

c0100320 <cputch>:
/* *
 * cputch - writes a single character @c to stdout, and it will
 * increace the value of counter pointed by @cnt.
 * */
static void
cputch(int c, int *cnt) {
c0100320:	55                   	push   %ebp
c0100321:	89 e5                	mov    %esp,%ebp
c0100323:	83 ec 18             	sub    $0x18,%esp
    cons_putc(c);
c0100326:	8b 45 08             	mov    0x8(%ebp),%eax
c0100329:	89 04 24             	mov    %eax,(%esp)
c010032c:	e8 ab 13 00 00       	call   c01016dc <cons_putc>
    (*cnt) ++;
c0100331:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100334:	8b 00                	mov    (%eax),%eax
c0100336:	8d 50 01             	lea    0x1(%eax),%edx
c0100339:	8b 45 0c             	mov    0xc(%ebp),%eax
c010033c:	89 10                	mov    %edx,(%eax)
}
c010033e:	90                   	nop
c010033f:	89 ec                	mov    %ebp,%esp
c0100341:	5d                   	pop    %ebp
c0100342:	c3                   	ret    

c0100343 <vcprintf>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want cprintf() instead.
 * */
int
vcprintf(const char *fmt, va_list ap) {
c0100343:	55                   	push   %ebp
c0100344:	89 e5                	mov    %esp,%ebp
c0100346:	83 ec 28             	sub    $0x28,%esp
    int cnt = 0;
c0100349:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    vprintfmt((void*)cputch, &cnt, fmt, ap);
c0100350:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100353:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0100357:	8b 45 08             	mov    0x8(%ebp),%eax
c010035a:	89 44 24 08          	mov    %eax,0x8(%esp)
c010035e:	8d 45 f4             	lea    -0xc(%ebp),%eax
c0100361:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100365:	c7 04 24 20 03 10 c0 	movl   $0xc0100320,(%esp)
c010036c:	e8 d3 b1 00 00       	call   c010b544 <vprintfmt>
    return cnt;
c0100371:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0100374:	89 ec                	mov    %ebp,%esp
c0100376:	5d                   	pop    %ebp
c0100377:	c3                   	ret    

c0100378 <cprintf>:
 *
 * The return value is the number of characters which would be
 * written to stdout.
 * */
int
cprintf(const char *fmt, ...) {
c0100378:	55                   	push   %ebp
c0100379:	89 e5                	mov    %esp,%ebp
c010037b:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    int cnt;
    va_start(ap, fmt);
c010037e:	8d 45 0c             	lea    0xc(%ebp),%eax
c0100381:	89 45 f0             	mov    %eax,-0x10(%ebp)
    cnt = vcprintf(fmt, ap);
c0100384:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100387:	89 44 24 04          	mov    %eax,0x4(%esp)
c010038b:	8b 45 08             	mov    0x8(%ebp),%eax
c010038e:	89 04 24             	mov    %eax,(%esp)
c0100391:	e8 ad ff ff ff       	call   c0100343 <vcprintf>
c0100396:	89 45 f4             	mov    %eax,-0xc(%ebp)
    va_end(ap);
    return cnt;
c0100399:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010039c:	89 ec                	mov    %ebp,%esp
c010039e:	5d                   	pop    %ebp
c010039f:	c3                   	ret    

c01003a0 <cputchar>:

/* cputchar - writes a single character to stdout */
void
cputchar(int c) {
c01003a0:	55                   	push   %ebp
c01003a1:	89 e5                	mov    %esp,%ebp
c01003a3:	83 ec 18             	sub    $0x18,%esp
    cons_putc(c);
c01003a6:	8b 45 08             	mov    0x8(%ebp),%eax
c01003a9:	89 04 24             	mov    %eax,(%esp)
c01003ac:	e8 2b 13 00 00       	call   c01016dc <cons_putc>
}
c01003b1:	90                   	nop
c01003b2:	89 ec                	mov    %ebp,%esp
c01003b4:	5d                   	pop    %ebp
c01003b5:	c3                   	ret    

c01003b6 <cputs>:
/* *
 * cputs- writes the string pointed by @str to stdout and
 * appends a newline character.
 * */
int
cputs(const char *str) {
c01003b6:	55                   	push   %ebp
c01003b7:	89 e5                	mov    %esp,%ebp
c01003b9:	83 ec 28             	sub    $0x28,%esp
    int cnt = 0;
c01003bc:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    char c;
    while ((c = *str ++) != '\0') {
c01003c3:	eb 13                	jmp    c01003d8 <cputs+0x22>
        cputch(c, &cnt);
c01003c5:	0f be 45 f7          	movsbl -0x9(%ebp),%eax
c01003c9:	8d 55 f0             	lea    -0x10(%ebp),%edx
c01003cc:	89 54 24 04          	mov    %edx,0x4(%esp)
c01003d0:	89 04 24             	mov    %eax,(%esp)
c01003d3:	e8 48 ff ff ff       	call   c0100320 <cputch>
    while ((c = *str ++) != '\0') {
c01003d8:	8b 45 08             	mov    0x8(%ebp),%eax
c01003db:	8d 50 01             	lea    0x1(%eax),%edx
c01003de:	89 55 08             	mov    %edx,0x8(%ebp)
c01003e1:	0f b6 00             	movzbl (%eax),%eax
c01003e4:	88 45 f7             	mov    %al,-0x9(%ebp)
c01003e7:	80 7d f7 00          	cmpb   $0x0,-0x9(%ebp)
c01003eb:	75 d8                	jne    c01003c5 <cputs+0xf>
    }
    cputch('\n', &cnt);
c01003ed:	8d 45 f0             	lea    -0x10(%ebp),%eax
c01003f0:	89 44 24 04          	mov    %eax,0x4(%esp)
c01003f4:	c7 04 24 0a 00 00 00 	movl   $0xa,(%esp)
c01003fb:	e8 20 ff ff ff       	call   c0100320 <cputch>
    return cnt;
c0100400:	8b 45 f0             	mov    -0x10(%ebp),%eax
}
c0100403:	89 ec                	mov    %ebp,%esp
c0100405:	5d                   	pop    %ebp
c0100406:	c3                   	ret    

c0100407 <getchar>:

/* getchar - reads a single non-zero character from stdin */
int
getchar(void) {
c0100407:	55                   	push   %ebp
c0100408:	89 e5                	mov    %esp,%ebp
c010040a:	83 ec 18             	sub    $0x18,%esp
    int c;
    while ((c = cons_getc()) == 0)
c010040d:	90                   	nop
c010040e:	e8 08 13 00 00       	call   c010171b <cons_getc>
c0100413:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0100416:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010041a:	74 f2                	je     c010040e <getchar+0x7>
        /* do nothing */;
    return c;
c010041c:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010041f:	89 ec                	mov    %ebp,%esp
c0100421:	5d                   	pop    %ebp
c0100422:	c3                   	ret    

c0100423 <stab_binsearch>:
 *      stab_binsearch(stabs, &left, &right, N_SO, 0xf0100184);
 * will exit setting left = 118, right = 554.
 * */
static void
stab_binsearch(const struct stab *stabs, int *region_left, int *region_right,
           int type, uintptr_t addr) {
c0100423:	55                   	push   %ebp
c0100424:	89 e5                	mov    %esp,%ebp
c0100426:	83 ec 20             	sub    $0x20,%esp
    int l = *region_left, r = *region_right, any_matches = 0;
c0100429:	8b 45 0c             	mov    0xc(%ebp),%eax
c010042c:	8b 00                	mov    (%eax),%eax
c010042e:	89 45 fc             	mov    %eax,-0x4(%ebp)
c0100431:	8b 45 10             	mov    0x10(%ebp),%eax
c0100434:	8b 00                	mov    (%eax),%eax
c0100436:	89 45 f8             	mov    %eax,-0x8(%ebp)
c0100439:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)

    while (l <= r) {
c0100440:	e9 ca 00 00 00       	jmp    c010050f <stab_binsearch+0xec>
        int true_m = (l + r) / 2, m = true_m;
c0100445:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0100448:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010044b:	01 d0                	add    %edx,%eax
c010044d:	89 c2                	mov    %eax,%edx
c010044f:	c1 ea 1f             	shr    $0x1f,%edx
c0100452:	01 d0                	add    %edx,%eax
c0100454:	d1 f8                	sar    %eax
c0100456:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0100459:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010045c:	89 45 f0             	mov    %eax,-0x10(%ebp)

        // search for earliest stab with right type
        while (m >= l && stabs[m].n_type != type) {
c010045f:	eb 03                	jmp    c0100464 <stab_binsearch+0x41>
            m --;
c0100461:	ff 4d f0             	decl   -0x10(%ebp)
        while (m >= l && stabs[m].n_type != type) {
c0100464:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100467:	3b 45 fc             	cmp    -0x4(%ebp),%eax
c010046a:	7c 1f                	jl     c010048b <stab_binsearch+0x68>
c010046c:	8b 55 f0             	mov    -0x10(%ebp),%edx
c010046f:	89 d0                	mov    %edx,%eax
c0100471:	01 c0                	add    %eax,%eax
c0100473:	01 d0                	add    %edx,%eax
c0100475:	c1 e0 02             	shl    $0x2,%eax
c0100478:	89 c2                	mov    %eax,%edx
c010047a:	8b 45 08             	mov    0x8(%ebp),%eax
c010047d:	01 d0                	add    %edx,%eax
c010047f:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c0100483:	0f b6 c0             	movzbl %al,%eax
c0100486:	39 45 14             	cmp    %eax,0x14(%ebp)
c0100489:	75 d6                	jne    c0100461 <stab_binsearch+0x3e>
        }
        if (m < l) {    // no match in [l, m]
c010048b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010048e:	3b 45 fc             	cmp    -0x4(%ebp),%eax
c0100491:	7d 09                	jge    c010049c <stab_binsearch+0x79>
            l = true_m + 1;
c0100493:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100496:	40                   	inc    %eax
c0100497:	89 45 fc             	mov    %eax,-0x4(%ebp)
            continue;
c010049a:	eb 73                	jmp    c010050f <stab_binsearch+0xec>
        }

        // actual binary search
        any_matches = 1;
c010049c:	c7 45 f4 01 00 00 00 	movl   $0x1,-0xc(%ebp)
        if (stabs[m].n_value < addr) {
c01004a3:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01004a6:	89 d0                	mov    %edx,%eax
c01004a8:	01 c0                	add    %eax,%eax
c01004aa:	01 d0                	add    %edx,%eax
c01004ac:	c1 e0 02             	shl    $0x2,%eax
c01004af:	89 c2                	mov    %eax,%edx
c01004b1:	8b 45 08             	mov    0x8(%ebp),%eax
c01004b4:	01 d0                	add    %edx,%eax
c01004b6:	8b 40 08             	mov    0x8(%eax),%eax
c01004b9:	39 45 18             	cmp    %eax,0x18(%ebp)
c01004bc:	76 11                	jbe    c01004cf <stab_binsearch+0xac>
            *region_left = m;
c01004be:	8b 45 0c             	mov    0xc(%ebp),%eax
c01004c1:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01004c4:	89 10                	mov    %edx,(%eax)
            l = true_m + 1;
c01004c6:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01004c9:	40                   	inc    %eax
c01004ca:	89 45 fc             	mov    %eax,-0x4(%ebp)
c01004cd:	eb 40                	jmp    c010050f <stab_binsearch+0xec>
        } else if (stabs[m].n_value > addr) {
c01004cf:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01004d2:	89 d0                	mov    %edx,%eax
c01004d4:	01 c0                	add    %eax,%eax
c01004d6:	01 d0                	add    %edx,%eax
c01004d8:	c1 e0 02             	shl    $0x2,%eax
c01004db:	89 c2                	mov    %eax,%edx
c01004dd:	8b 45 08             	mov    0x8(%ebp),%eax
c01004e0:	01 d0                	add    %edx,%eax
c01004e2:	8b 40 08             	mov    0x8(%eax),%eax
c01004e5:	39 45 18             	cmp    %eax,0x18(%ebp)
c01004e8:	73 14                	jae    c01004fe <stab_binsearch+0xdb>
            *region_right = m - 1;
c01004ea:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01004ed:	8d 50 ff             	lea    -0x1(%eax),%edx
c01004f0:	8b 45 10             	mov    0x10(%ebp),%eax
c01004f3:	89 10                	mov    %edx,(%eax)
            r = m - 1;
c01004f5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01004f8:	48                   	dec    %eax
c01004f9:	89 45 f8             	mov    %eax,-0x8(%ebp)
c01004fc:	eb 11                	jmp    c010050f <stab_binsearch+0xec>
        } else {
            // exact match for 'addr', but continue loop to find
            // *region_right
            *region_left = m;
c01004fe:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100501:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0100504:	89 10                	mov    %edx,(%eax)
            l = m;
c0100506:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100509:	89 45 fc             	mov    %eax,-0x4(%ebp)
            addr ++;
c010050c:	ff 45 18             	incl   0x18(%ebp)
    while (l <= r) {
c010050f:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100512:	3b 45 f8             	cmp    -0x8(%ebp),%eax
c0100515:	0f 8e 2a ff ff ff    	jle    c0100445 <stab_binsearch+0x22>
        }
    }

    if (!any_matches) {
c010051b:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010051f:	75 0f                	jne    c0100530 <stab_binsearch+0x10d>
        *region_right = *region_left - 1;
c0100521:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100524:	8b 00                	mov    (%eax),%eax
c0100526:	8d 50 ff             	lea    -0x1(%eax),%edx
c0100529:	8b 45 10             	mov    0x10(%ebp),%eax
c010052c:	89 10                	mov    %edx,(%eax)
        l = *region_right;
        for (; l > *region_left && stabs[l].n_type != type; l --)
            /* do nothing */;
        *region_left = l;
    }
}
c010052e:	eb 3e                	jmp    c010056e <stab_binsearch+0x14b>
        l = *region_right;
c0100530:	8b 45 10             	mov    0x10(%ebp),%eax
c0100533:	8b 00                	mov    (%eax),%eax
c0100535:	89 45 fc             	mov    %eax,-0x4(%ebp)
        for (; l > *region_left && stabs[l].n_type != type; l --)
c0100538:	eb 03                	jmp    c010053d <stab_binsearch+0x11a>
c010053a:	ff 4d fc             	decl   -0x4(%ebp)
c010053d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100540:	8b 00                	mov    (%eax),%eax
c0100542:	39 45 fc             	cmp    %eax,-0x4(%ebp)
c0100545:	7e 1f                	jle    c0100566 <stab_binsearch+0x143>
c0100547:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010054a:	89 d0                	mov    %edx,%eax
c010054c:	01 c0                	add    %eax,%eax
c010054e:	01 d0                	add    %edx,%eax
c0100550:	c1 e0 02             	shl    $0x2,%eax
c0100553:	89 c2                	mov    %eax,%edx
c0100555:	8b 45 08             	mov    0x8(%ebp),%eax
c0100558:	01 d0                	add    %edx,%eax
c010055a:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c010055e:	0f b6 c0             	movzbl %al,%eax
c0100561:	39 45 14             	cmp    %eax,0x14(%ebp)
c0100564:	75 d4                	jne    c010053a <stab_binsearch+0x117>
        *region_left = l;
c0100566:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100569:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010056c:	89 10                	mov    %edx,(%eax)
}
c010056e:	90                   	nop
c010056f:	89 ec                	mov    %ebp,%esp
c0100571:	5d                   	pop    %ebp
c0100572:	c3                   	ret    

c0100573 <debuginfo_eip>:
 * the specified instruction address, @addr.  Returns 0 if information
 * was found, and negative if not.  But even if it returns negative it
 * has stored some information into '*info'.
 * */
int
debuginfo_eip(uintptr_t addr, struct eipdebuginfo *info) {
c0100573:	55                   	push   %ebp
c0100574:	89 e5                	mov    %esp,%ebp
c0100576:	83 ec 58             	sub    $0x58,%esp
    const struct stab *stabs, *stab_end;
    const char *stabstr, *stabstr_end;

    info->eip_file = "<unknown>";
c0100579:	8b 45 0c             	mov    0xc(%ebp),%eax
c010057c:	c7 00 2c c0 10 c0    	movl   $0xc010c02c,(%eax)
    info->eip_line = 0;
c0100582:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100585:	c7 40 04 00 00 00 00 	movl   $0x0,0x4(%eax)
    info->eip_fn_name = "<unknown>";
c010058c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010058f:	c7 40 08 2c c0 10 c0 	movl   $0xc010c02c,0x8(%eax)
    info->eip_fn_namelen = 9;
c0100596:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100599:	c7 40 0c 09 00 00 00 	movl   $0x9,0xc(%eax)
    info->eip_fn_addr = addr;
c01005a0:	8b 45 0c             	mov    0xc(%ebp),%eax
c01005a3:	8b 55 08             	mov    0x8(%ebp),%edx
c01005a6:	89 50 10             	mov    %edx,0x10(%eax)
    info->eip_fn_narg = 0;
c01005a9:	8b 45 0c             	mov    0xc(%ebp),%eax
c01005ac:	c7 40 14 00 00 00 00 	movl   $0x0,0x14(%eax)

    // find the relevant set of stabs
    if (addr >= KERNBASE) {
c01005b3:	81 7d 08 ff ff ff bf 	cmpl   $0xbfffffff,0x8(%ebp)
c01005ba:	76 21                	jbe    c01005dd <debuginfo_eip+0x6a>
        stabs = __STAB_BEGIN__;
c01005bc:	c7 45 f4 e0 e7 10 c0 	movl   $0xc010e7e0,-0xc(%ebp)
        stab_end = __STAB_END__;
c01005c3:	c7 45 f0 5c 4c 12 c0 	movl   $0xc0124c5c,-0x10(%ebp)
        stabstr = __STABSTR_BEGIN__;
c01005ca:	c7 45 ec 5d 4c 12 c0 	movl   $0xc0124c5d,-0x14(%ebp)
        stabstr_end = __STABSTR_END__;
c01005d1:	c7 45 e8 8d c9 12 c0 	movl   $0xc012c98d,-0x18(%ebp)
c01005d8:	e9 e8 00 00 00       	jmp    c01006c5 <debuginfo_eip+0x152>
    }
    else {
        // user-program linker script, tools/user.ld puts the information about the
        // program's stabs (included __STAB_BEGIN__, __STAB_END__, __STABSTR_BEGIN__,
        // and __STABSTR_END__) in a structure located at virtual address USTAB.
        const struct userstabdata *usd = (struct userstabdata *)USTAB;
c01005dd:	c7 45 e4 00 00 20 00 	movl   $0x200000,-0x1c(%ebp)

        // make sure that debugger (current process) can access this memory
        struct mm_struct *mm;
        if (current == NULL || (mm = current->mm) == NULL) {
c01005e4:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01005e9:	85 c0                	test   %eax,%eax
c01005eb:	74 11                	je     c01005fe <debuginfo_eip+0x8b>
c01005ed:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01005f2:	8b 40 18             	mov    0x18(%eax),%eax
c01005f5:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01005f8:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c01005fc:	75 0a                	jne    c0100608 <debuginfo_eip+0x95>
            return -1;
c01005fe:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c0100603:	e9 85 03 00 00       	jmp    c010098d <debuginfo_eip+0x41a>
        }
        if (!user_mem_check(mm, (uintptr_t)usd, sizeof(struct userstabdata), 0)) {
c0100608:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010060b:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0100612:	00 
c0100613:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
c010061a:	00 
c010061b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010061f:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0100622:	89 04 24             	mov    %eax,(%esp)
c0100625:	e8 30 8a 00 00       	call   c010905a <user_mem_check>
c010062a:	85 c0                	test   %eax,%eax
c010062c:	75 0a                	jne    c0100638 <debuginfo_eip+0xc5>
            return -1;
c010062e:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c0100633:	e9 55 03 00 00       	jmp    c010098d <debuginfo_eip+0x41a>
        }

        stabs = usd->stabs;
c0100638:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010063b:	8b 00                	mov    (%eax),%eax
c010063d:	89 45 f4             	mov    %eax,-0xc(%ebp)
        stab_end = usd->stab_end;
c0100640:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100643:	8b 40 04             	mov    0x4(%eax),%eax
c0100646:	89 45 f0             	mov    %eax,-0x10(%ebp)
        stabstr = usd->stabstr;
c0100649:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010064c:	8b 40 08             	mov    0x8(%eax),%eax
c010064f:	89 45 ec             	mov    %eax,-0x14(%ebp)
        stabstr_end = usd->stabstr_end;
c0100652:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100655:	8b 40 0c             	mov    0xc(%eax),%eax
c0100658:	89 45 e8             	mov    %eax,-0x18(%ebp)

        // make sure the STABS and string table memory is valid
        if (!user_mem_check(mm, (uintptr_t)stabs, (uintptr_t)stab_end - (uintptr_t)stabs, 0)) {
c010065b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010065e:	8b 4d f4             	mov    -0xc(%ebp),%ecx
c0100661:	29 c8                	sub    %ecx,%eax
c0100663:	89 c2                	mov    %eax,%edx
c0100665:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100668:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c010066f:	00 
c0100670:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100674:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100678:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010067b:	89 04 24             	mov    %eax,(%esp)
c010067e:	e8 d7 89 00 00       	call   c010905a <user_mem_check>
c0100683:	85 c0                	test   %eax,%eax
c0100685:	75 0a                	jne    c0100691 <debuginfo_eip+0x11e>
            return -1;
c0100687:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c010068c:	e9 fc 02 00 00       	jmp    c010098d <debuginfo_eip+0x41a>
        }
        if (!user_mem_check(mm, (uintptr_t)stabstr, stabstr_end - stabstr, 0)) {
c0100691:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0100694:	2b 45 ec             	sub    -0x14(%ebp),%eax
c0100697:	89 c2                	mov    %eax,%edx
c0100699:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010069c:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c01006a3:	00 
c01006a4:	89 54 24 08          	mov    %edx,0x8(%esp)
c01006a8:	89 44 24 04          	mov    %eax,0x4(%esp)
c01006ac:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01006af:	89 04 24             	mov    %eax,(%esp)
c01006b2:	e8 a3 89 00 00       	call   c010905a <user_mem_check>
c01006b7:	85 c0                	test   %eax,%eax
c01006b9:	75 0a                	jne    c01006c5 <debuginfo_eip+0x152>
            return -1;
c01006bb:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c01006c0:	e9 c8 02 00 00       	jmp    c010098d <debuginfo_eip+0x41a>
        }
    }

    // String table validity checks
    if (stabstr_end <= stabstr || stabstr_end[-1] != 0) {
c01006c5:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01006c8:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c01006cb:	76 0b                	jbe    c01006d8 <debuginfo_eip+0x165>
c01006cd:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01006d0:	48                   	dec    %eax
c01006d1:	0f b6 00             	movzbl (%eax),%eax
c01006d4:	84 c0                	test   %al,%al
c01006d6:	74 0a                	je     c01006e2 <debuginfo_eip+0x16f>
        return -1;
c01006d8:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c01006dd:	e9 ab 02 00 00       	jmp    c010098d <debuginfo_eip+0x41a>
    // 'eip'.  First, we find the basic source file containing 'eip'.
    // Then, we look in that source file for the function.  Then we look
    // for the line number.

    // Search the entire set of stabs for the source file (type N_SO).
    int lfile = 0, rfile = (stab_end - stabs) - 1;
c01006e2:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c01006e9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01006ec:	2b 45 f4             	sub    -0xc(%ebp),%eax
c01006ef:	c1 f8 02             	sar    $0x2,%eax
c01006f2:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
c01006f8:	48                   	dec    %eax
c01006f9:	89 45 d8             	mov    %eax,-0x28(%ebp)
    stab_binsearch(stabs, &lfile, &rfile, N_SO, addr);
c01006fc:	8b 45 08             	mov    0x8(%ebp),%eax
c01006ff:	89 44 24 10          	mov    %eax,0x10(%esp)
c0100703:	c7 44 24 0c 64 00 00 	movl   $0x64,0xc(%esp)
c010070a:	00 
c010070b:	8d 45 d8             	lea    -0x28(%ebp),%eax
c010070e:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100712:	8d 45 dc             	lea    -0x24(%ebp),%eax
c0100715:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100719:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010071c:	89 04 24             	mov    %eax,(%esp)
c010071f:	e8 ff fc ff ff       	call   c0100423 <stab_binsearch>
    if (lfile == 0)
c0100724:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0100727:	85 c0                	test   %eax,%eax
c0100729:	75 0a                	jne    c0100735 <debuginfo_eip+0x1c2>
        return -1;
c010072b:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c0100730:	e9 58 02 00 00       	jmp    c010098d <debuginfo_eip+0x41a>

    // Search within that file's stabs for the function definition
    // (N_FUN).
    int lfun = lfile, rfun = rfile;
c0100735:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0100738:	89 45 d4             	mov    %eax,-0x2c(%ebp)
c010073b:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010073e:	89 45 d0             	mov    %eax,-0x30(%ebp)
    int lline, rline;
    stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr);
c0100741:	8b 45 08             	mov    0x8(%ebp),%eax
c0100744:	89 44 24 10          	mov    %eax,0x10(%esp)
c0100748:	c7 44 24 0c 24 00 00 	movl   $0x24,0xc(%esp)
c010074f:	00 
c0100750:	8d 45 d0             	lea    -0x30(%ebp),%eax
c0100753:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100757:	8d 45 d4             	lea    -0x2c(%ebp),%eax
c010075a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010075e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100761:	89 04 24             	mov    %eax,(%esp)
c0100764:	e8 ba fc ff ff       	call   c0100423 <stab_binsearch>

    if (lfun <= rfun) {
c0100769:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010076c:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010076f:	39 c2                	cmp    %eax,%edx
c0100771:	7f 78                	jg     c01007eb <debuginfo_eip+0x278>
        // stabs[lfun] points to the function name
        // in the string table, but check bounds just in case.
        if (stabs[lfun].n_strx < stabstr_end - stabstr) {
c0100773:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100776:	89 c2                	mov    %eax,%edx
c0100778:	89 d0                	mov    %edx,%eax
c010077a:	01 c0                	add    %eax,%eax
c010077c:	01 d0                	add    %edx,%eax
c010077e:	c1 e0 02             	shl    $0x2,%eax
c0100781:	89 c2                	mov    %eax,%edx
c0100783:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100786:	01 d0                	add    %edx,%eax
c0100788:	8b 10                	mov    (%eax),%edx
c010078a:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010078d:	2b 45 ec             	sub    -0x14(%ebp),%eax
c0100790:	39 c2                	cmp    %eax,%edx
c0100792:	73 22                	jae    c01007b6 <debuginfo_eip+0x243>
            info->eip_fn_name = stabstr + stabs[lfun].n_strx;
c0100794:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100797:	89 c2                	mov    %eax,%edx
c0100799:	89 d0                	mov    %edx,%eax
c010079b:	01 c0                	add    %eax,%eax
c010079d:	01 d0                	add    %edx,%eax
c010079f:	c1 e0 02             	shl    $0x2,%eax
c01007a2:	89 c2                	mov    %eax,%edx
c01007a4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01007a7:	01 d0                	add    %edx,%eax
c01007a9:	8b 10                	mov    (%eax),%edx
c01007ab:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01007ae:	01 c2                	add    %eax,%edx
c01007b0:	8b 45 0c             	mov    0xc(%ebp),%eax
c01007b3:	89 50 08             	mov    %edx,0x8(%eax)
        }
        info->eip_fn_addr = stabs[lfun].n_value;
c01007b6:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01007b9:	89 c2                	mov    %eax,%edx
c01007bb:	89 d0                	mov    %edx,%eax
c01007bd:	01 c0                	add    %eax,%eax
c01007bf:	01 d0                	add    %edx,%eax
c01007c1:	c1 e0 02             	shl    $0x2,%eax
c01007c4:	89 c2                	mov    %eax,%edx
c01007c6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01007c9:	01 d0                	add    %edx,%eax
c01007cb:	8b 50 08             	mov    0x8(%eax),%edx
c01007ce:	8b 45 0c             	mov    0xc(%ebp),%eax
c01007d1:	89 50 10             	mov    %edx,0x10(%eax)
        addr -= info->eip_fn_addr;
c01007d4:	8b 45 0c             	mov    0xc(%ebp),%eax
c01007d7:	8b 40 10             	mov    0x10(%eax),%eax
c01007da:	29 45 08             	sub    %eax,0x8(%ebp)
        // Search within the function definition for the line number.
        lline = lfun;
c01007dd:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01007e0:	89 45 cc             	mov    %eax,-0x34(%ebp)
        rline = rfun;
c01007e3:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01007e6:	89 45 c8             	mov    %eax,-0x38(%ebp)
c01007e9:	eb 15                	jmp    c0100800 <debuginfo_eip+0x28d>
    } else {
        // Couldn't find function stab!  Maybe we're in an assembly
        // file.  Search the whole file for the line number.
        info->eip_fn_addr = addr;
c01007eb:	8b 45 0c             	mov    0xc(%ebp),%eax
c01007ee:	8b 55 08             	mov    0x8(%ebp),%edx
c01007f1:	89 50 10             	mov    %edx,0x10(%eax)
        lline = lfile;
c01007f4:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01007f7:	89 45 cc             	mov    %eax,-0x34(%ebp)
        rline = rfile;
c01007fa:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01007fd:	89 45 c8             	mov    %eax,-0x38(%ebp)
    }
    info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name;
c0100800:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100803:	8b 40 08             	mov    0x8(%eax),%eax
c0100806:	c7 44 24 04 3a 00 00 	movl   $0x3a,0x4(%esp)
c010080d:	00 
c010080e:	89 04 24             	mov    %eax,(%esp)
c0100811:	e8 53 b4 00 00       	call   c010bc69 <strfind>
c0100816:	8b 55 0c             	mov    0xc(%ebp),%edx
c0100819:	8b 4a 08             	mov    0x8(%edx),%ecx
c010081c:	29 c8                	sub    %ecx,%eax
c010081e:	89 c2                	mov    %eax,%edx
c0100820:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100823:	89 50 0c             	mov    %edx,0xc(%eax)

    // Search within [lline, rline] for the line number stab.
    // If found, set info->eip_line to the right line number.
    // If not found, return -1.
    stab_binsearch(stabs, &lline, &rline, N_SLINE, addr);
c0100826:	8b 45 08             	mov    0x8(%ebp),%eax
c0100829:	89 44 24 10          	mov    %eax,0x10(%esp)
c010082d:	c7 44 24 0c 44 00 00 	movl   $0x44,0xc(%esp)
c0100834:	00 
c0100835:	8d 45 c8             	lea    -0x38(%ebp),%eax
c0100838:	89 44 24 08          	mov    %eax,0x8(%esp)
c010083c:	8d 45 cc             	lea    -0x34(%ebp),%eax
c010083f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100843:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100846:	89 04 24             	mov    %eax,(%esp)
c0100849:	e8 d5 fb ff ff       	call   c0100423 <stab_binsearch>
    if (lline <= rline) {
c010084e:	8b 55 cc             	mov    -0x34(%ebp),%edx
c0100851:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0100854:	39 c2                	cmp    %eax,%edx
c0100856:	7f 23                	jg     c010087b <debuginfo_eip+0x308>
        info->eip_line = stabs[rline].n_desc;
c0100858:	8b 45 c8             	mov    -0x38(%ebp),%eax
c010085b:	89 c2                	mov    %eax,%edx
c010085d:	89 d0                	mov    %edx,%eax
c010085f:	01 c0                	add    %eax,%eax
c0100861:	01 d0                	add    %edx,%eax
c0100863:	c1 e0 02             	shl    $0x2,%eax
c0100866:	89 c2                	mov    %eax,%edx
c0100868:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010086b:	01 d0                	add    %edx,%eax
c010086d:	0f b7 40 06          	movzwl 0x6(%eax),%eax
c0100871:	89 c2                	mov    %eax,%edx
c0100873:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100876:	89 50 04             	mov    %edx,0x4(%eax)

    // Search backwards from the line number for the relevant filename stab.
    // We can't just use the "lfile" stab because inlined functions
    // can interpolate code from a different file!
    // Such included source files use the N_SOL stab type.
    while (lline >= lfile
c0100879:	eb 11                	jmp    c010088c <debuginfo_eip+0x319>
        return -1;
c010087b:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c0100880:	e9 08 01 00 00       	jmp    c010098d <debuginfo_eip+0x41a>
           && stabs[lline].n_type != N_SOL
           && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) {
        lline --;
c0100885:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0100888:	48                   	dec    %eax
c0100889:	89 45 cc             	mov    %eax,-0x34(%ebp)
    while (lline >= lfile
c010088c:	8b 55 cc             	mov    -0x34(%ebp),%edx
c010088f:	8b 45 dc             	mov    -0x24(%ebp),%eax
           && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) {
c0100892:	39 c2                	cmp    %eax,%edx
c0100894:	7c 56                	jl     c01008ec <debuginfo_eip+0x379>
           && stabs[lline].n_type != N_SOL
c0100896:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0100899:	89 c2                	mov    %eax,%edx
c010089b:	89 d0                	mov    %edx,%eax
c010089d:	01 c0                	add    %eax,%eax
c010089f:	01 d0                	add    %edx,%eax
c01008a1:	c1 e0 02             	shl    $0x2,%eax
c01008a4:	89 c2                	mov    %eax,%edx
c01008a6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01008a9:	01 d0                	add    %edx,%eax
c01008ab:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c01008af:	3c 84                	cmp    $0x84,%al
c01008b1:	74 39                	je     c01008ec <debuginfo_eip+0x379>
           && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) {
c01008b3:	8b 45 cc             	mov    -0x34(%ebp),%eax
c01008b6:	89 c2                	mov    %eax,%edx
c01008b8:	89 d0                	mov    %edx,%eax
c01008ba:	01 c0                	add    %eax,%eax
c01008bc:	01 d0                	add    %edx,%eax
c01008be:	c1 e0 02             	shl    $0x2,%eax
c01008c1:	89 c2                	mov    %eax,%edx
c01008c3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01008c6:	01 d0                	add    %edx,%eax
c01008c8:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c01008cc:	3c 64                	cmp    $0x64,%al
c01008ce:	75 b5                	jne    c0100885 <debuginfo_eip+0x312>
c01008d0:	8b 45 cc             	mov    -0x34(%ebp),%eax
c01008d3:	89 c2                	mov    %eax,%edx
c01008d5:	89 d0                	mov    %edx,%eax
c01008d7:	01 c0                	add    %eax,%eax
c01008d9:	01 d0                	add    %edx,%eax
c01008db:	c1 e0 02             	shl    $0x2,%eax
c01008de:	89 c2                	mov    %eax,%edx
c01008e0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01008e3:	01 d0                	add    %edx,%eax
c01008e5:	8b 40 08             	mov    0x8(%eax),%eax
c01008e8:	85 c0                	test   %eax,%eax
c01008ea:	74 99                	je     c0100885 <debuginfo_eip+0x312>
    }
    if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) {
c01008ec:	8b 55 cc             	mov    -0x34(%ebp),%edx
c01008ef:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01008f2:	39 c2                	cmp    %eax,%edx
c01008f4:	7c 42                	jl     c0100938 <debuginfo_eip+0x3c5>
c01008f6:	8b 45 cc             	mov    -0x34(%ebp),%eax
c01008f9:	89 c2                	mov    %eax,%edx
c01008fb:	89 d0                	mov    %edx,%eax
c01008fd:	01 c0                	add    %eax,%eax
c01008ff:	01 d0                	add    %edx,%eax
c0100901:	c1 e0 02             	shl    $0x2,%eax
c0100904:	89 c2                	mov    %eax,%edx
c0100906:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100909:	01 d0                	add    %edx,%eax
c010090b:	8b 10                	mov    (%eax),%edx
c010090d:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0100910:	2b 45 ec             	sub    -0x14(%ebp),%eax
c0100913:	39 c2                	cmp    %eax,%edx
c0100915:	73 21                	jae    c0100938 <debuginfo_eip+0x3c5>
        info->eip_file = stabstr + stabs[lline].n_strx;
c0100917:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010091a:	89 c2                	mov    %eax,%edx
c010091c:	89 d0                	mov    %edx,%eax
c010091e:	01 c0                	add    %eax,%eax
c0100920:	01 d0                	add    %edx,%eax
c0100922:	c1 e0 02             	shl    $0x2,%eax
c0100925:	89 c2                	mov    %eax,%edx
c0100927:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010092a:	01 d0                	add    %edx,%eax
c010092c:	8b 10                	mov    (%eax),%edx
c010092e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100931:	01 c2                	add    %eax,%edx
c0100933:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100936:	89 10                	mov    %edx,(%eax)
    }

    // Set eip_fn_narg to the number of arguments taken by the function,
    // or 0 if there was no containing function.
    if (lfun < rfun) {
c0100938:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010093b:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010093e:	39 c2                	cmp    %eax,%edx
c0100940:	7d 46                	jge    c0100988 <debuginfo_eip+0x415>
        for (lline = lfun + 1;
c0100942:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100945:	40                   	inc    %eax
c0100946:	89 45 cc             	mov    %eax,-0x34(%ebp)
c0100949:	eb 16                	jmp    c0100961 <debuginfo_eip+0x3ee>
             lline < rfun && stabs[lline].n_type == N_PSYM;
             lline ++) {
            info->eip_fn_narg ++;
c010094b:	8b 45 0c             	mov    0xc(%ebp),%eax
c010094e:	8b 40 14             	mov    0x14(%eax),%eax
c0100951:	8d 50 01             	lea    0x1(%eax),%edx
c0100954:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100957:	89 50 14             	mov    %edx,0x14(%eax)
             lline ++) {
c010095a:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010095d:	40                   	inc    %eax
c010095e:	89 45 cc             	mov    %eax,-0x34(%ebp)
             lline < rfun && stabs[lline].n_type == N_PSYM;
c0100961:	8b 55 cc             	mov    -0x34(%ebp),%edx
c0100964:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0100967:	39 c2                	cmp    %eax,%edx
c0100969:	7d 1d                	jge    c0100988 <debuginfo_eip+0x415>
c010096b:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010096e:	89 c2                	mov    %eax,%edx
c0100970:	89 d0                	mov    %edx,%eax
c0100972:	01 c0                	add    %eax,%eax
c0100974:	01 d0                	add    %edx,%eax
c0100976:	c1 e0 02             	shl    $0x2,%eax
c0100979:	89 c2                	mov    %eax,%edx
c010097b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010097e:	01 d0                	add    %edx,%eax
c0100980:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c0100984:	3c a0                	cmp    $0xa0,%al
c0100986:	74 c3                	je     c010094b <debuginfo_eip+0x3d8>
        }
    }
    return 0;
c0100988:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010098d:	89 ec                	mov    %ebp,%esp
c010098f:	5d                   	pop    %ebp
c0100990:	c3                   	ret    

c0100991 <print_kerninfo>:
 * print_kerninfo - print the information about kernel, including the location
 * of kernel entry, the start addresses of data and text segements, the start
 * address of free memory and how many memory that kernel has used.
 * */
void
print_kerninfo(void) {
c0100991:	55                   	push   %ebp
c0100992:	89 e5                	mov    %esp,%ebp
c0100994:	83 ec 18             	sub    $0x18,%esp
    extern char etext[], edata[], end[], kern_init[];
    cprintf("Special kernel symbols:\n");
c0100997:	c7 04 24 36 c0 10 c0 	movl   $0xc010c036,(%esp)
c010099e:	e8 d5 f9 ff ff       	call   c0100378 <cprintf>
    cprintf("  entry  0x%08x (phys)\n", kern_init);
c01009a3:	c7 44 24 04 36 00 10 	movl   $0xc0100036,0x4(%esp)
c01009aa:	c0 
c01009ab:	c7 04 24 4f c0 10 c0 	movl   $0xc010c04f,(%esp)
c01009b2:	e8 c1 f9 ff ff       	call   c0100378 <cprintf>
    cprintf("  etext  0x%08x (phys)\n", etext);
c01009b7:	c7 44 24 04 7d bf 10 	movl   $0xc010bf7d,0x4(%esp)
c01009be:	c0 
c01009bf:	c7 04 24 67 c0 10 c0 	movl   $0xc010c067,(%esp)
c01009c6:	e8 ad f9 ff ff       	call   c0100378 <cprintf>
    cprintf("  edata  0x%08x (phys)\n", edata);
c01009cb:	c7 44 24 04 00 30 1a 	movl   $0xc01a3000,0x4(%esp)
c01009d2:	c0 
c01009d3:	c7 04 24 7f c0 10 c0 	movl   $0xc010c07f,(%esp)
c01009da:	e8 99 f9 ff ff       	call   c0100378 <cprintf>
    cprintf("  end    0x%08x (phys)\n", end);
c01009df:	c7 44 24 04 54 61 1a 	movl   $0xc01a6154,0x4(%esp)
c01009e6:	c0 
c01009e7:	c7 04 24 97 c0 10 c0 	movl   $0xc010c097,(%esp)
c01009ee:	e8 85 f9 ff ff       	call   c0100378 <cprintf>
    cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024);
c01009f3:	b8 54 61 1a c0       	mov    $0xc01a6154,%eax
c01009f8:	2d 36 00 10 c0       	sub    $0xc0100036,%eax
c01009fd:	05 ff 03 00 00       	add    $0x3ff,%eax
c0100a02:	8d 90 ff 03 00 00    	lea    0x3ff(%eax),%edx
c0100a08:	85 c0                	test   %eax,%eax
c0100a0a:	0f 48 c2             	cmovs  %edx,%eax
c0100a0d:	c1 f8 0a             	sar    $0xa,%eax
c0100a10:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100a14:	c7 04 24 b0 c0 10 c0 	movl   $0xc010c0b0,(%esp)
c0100a1b:	e8 58 f9 ff ff       	call   c0100378 <cprintf>
}
c0100a20:	90                   	nop
c0100a21:	89 ec                	mov    %ebp,%esp
c0100a23:	5d                   	pop    %ebp
c0100a24:	c3                   	ret    

c0100a25 <print_debuginfo>:
/* *
 * print_debuginfo - read and print the stat information for the address @eip,
 * and info.eip_fn_addr should be the first address of the related function.
 * */
void
print_debuginfo(uintptr_t eip) {
c0100a25:	55                   	push   %ebp
c0100a26:	89 e5                	mov    %esp,%ebp
c0100a28:	81 ec 48 01 00 00    	sub    $0x148,%esp
    struct eipdebuginfo info;
    if (debuginfo_eip(eip, &info) != 0) {
c0100a2e:	8d 45 dc             	lea    -0x24(%ebp),%eax
c0100a31:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100a35:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a38:	89 04 24             	mov    %eax,(%esp)
c0100a3b:	e8 33 fb ff ff       	call   c0100573 <debuginfo_eip>
c0100a40:	85 c0                	test   %eax,%eax
c0100a42:	74 15                	je     c0100a59 <print_debuginfo+0x34>
        cprintf("    <unknow>: -- 0x%08x --\n", eip);
c0100a44:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a47:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100a4b:	c7 04 24 da c0 10 c0 	movl   $0xc010c0da,(%esp)
c0100a52:	e8 21 f9 ff ff       	call   c0100378 <cprintf>
        }
        fnname[j] = '\0';
        cprintf("    %s:%d: %s+%d\n", info.eip_file, info.eip_line,
                fnname, eip - info.eip_fn_addr);
    }
}
c0100a57:	eb 6c                	jmp    c0100ac5 <print_debuginfo+0xa0>
        for (j = 0; j < info.eip_fn_namelen; j ++) {
c0100a59:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0100a60:	eb 1b                	jmp    c0100a7d <print_debuginfo+0x58>
            fnname[j] = info.eip_fn_name[j];
c0100a62:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0100a65:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100a68:	01 d0                	add    %edx,%eax
c0100a6a:	0f b6 10             	movzbl (%eax),%edx
c0100a6d:	8d 8d dc fe ff ff    	lea    -0x124(%ebp),%ecx
c0100a73:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100a76:	01 c8                	add    %ecx,%eax
c0100a78:	88 10                	mov    %dl,(%eax)
        for (j = 0; j < info.eip_fn_namelen; j ++) {
c0100a7a:	ff 45 f4             	incl   -0xc(%ebp)
c0100a7d:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0100a80:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0100a83:	7c dd                	jl     c0100a62 <print_debuginfo+0x3d>
        fnname[j] = '\0';
c0100a85:	8d 95 dc fe ff ff    	lea    -0x124(%ebp),%edx
c0100a8b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100a8e:	01 d0                	add    %edx,%eax
c0100a90:	c6 00 00             	movb   $0x0,(%eax)
                fnname, eip - info.eip_fn_addr);
c0100a93:	8b 55 ec             	mov    -0x14(%ebp),%edx
        cprintf("    %s:%d: %s+%d\n", info.eip_file, info.eip_line,
c0100a96:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a99:	29 d0                	sub    %edx,%eax
c0100a9b:	89 c1                	mov    %eax,%ecx
c0100a9d:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0100aa0:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0100aa3:	89 4c 24 10          	mov    %ecx,0x10(%esp)
c0100aa7:	8d 8d dc fe ff ff    	lea    -0x124(%ebp),%ecx
c0100aad:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c0100ab1:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100ab5:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100ab9:	c7 04 24 f6 c0 10 c0 	movl   $0xc010c0f6,(%esp)
c0100ac0:	e8 b3 f8 ff ff       	call   c0100378 <cprintf>
}
c0100ac5:	90                   	nop
c0100ac6:	89 ec                	mov    %ebp,%esp
c0100ac8:	5d                   	pop    %ebp
c0100ac9:	c3                   	ret    

c0100aca <read_eip>:

static __noinline uint32_t
read_eip(void) {
c0100aca:	55                   	push   %ebp
c0100acb:	89 e5                	mov    %esp,%ebp
c0100acd:	83 ec 10             	sub    $0x10,%esp
    uint32_t eip;
    asm volatile("movl 4(%%ebp), %0" : "=r" (eip));
c0100ad0:	8b 45 04             	mov    0x4(%ebp),%eax
c0100ad3:	89 45 fc             	mov    %eax,-0x4(%ebp)
    return eip;
c0100ad6:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0100ad9:	89 ec                	mov    %ebp,%esp
c0100adb:	5d                   	pop    %ebp
c0100adc:	c3                   	ret    

c0100add <print_stackframe>:
 *
 * Note that, the length of ebp-chain is limited. In boot/bootasm.S, before jumping
 * to the kernel entry, the value of ebp has been set to zero, that's the boundary.
 * */
void
print_stackframe(void) {
c0100add:	55                   	push   %ebp
c0100ade:	89 e5                	mov    %esp,%ebp
      *    (3.4) call print_debuginfo(eip-1) to print the C calling function name and line number, etc.
      *    (3.5) popup a calling stackframe
      *           NOTICE: the calling funciton's return addr eip  = ss:[ebp+4]
      *                   the calling funciton's ebp = ss:[ebp]
      */
}
c0100ae0:	90                   	nop
c0100ae1:	5d                   	pop    %ebp
c0100ae2:	c3                   	ret    

c0100ae3 <parse>:
#define MAXARGS         16
#define WHITESPACE      " \t\n\r"

/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
c0100ae3:	55                   	push   %ebp
c0100ae4:	89 e5                	mov    %esp,%ebp
c0100ae6:	83 ec 28             	sub    $0x28,%esp
    int argc = 0;
c0100ae9:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    while (1) {
        // find global whitespace
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c0100af0:	eb 0c                	jmp    c0100afe <parse+0x1b>
            *buf ++ = '\0';
c0100af2:	8b 45 08             	mov    0x8(%ebp),%eax
c0100af5:	8d 50 01             	lea    0x1(%eax),%edx
c0100af8:	89 55 08             	mov    %edx,0x8(%ebp)
c0100afb:	c6 00 00             	movb   $0x0,(%eax)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c0100afe:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b01:	0f b6 00             	movzbl (%eax),%eax
c0100b04:	84 c0                	test   %al,%al
c0100b06:	74 1d                	je     c0100b25 <parse+0x42>
c0100b08:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b0b:	0f b6 00             	movzbl (%eax),%eax
c0100b0e:	0f be c0             	movsbl %al,%eax
c0100b11:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100b15:	c7 04 24 88 c1 10 c0 	movl   $0xc010c188,(%esp)
c0100b1c:	e8 14 b1 00 00       	call   c010bc35 <strchr>
c0100b21:	85 c0                	test   %eax,%eax
c0100b23:	75 cd                	jne    c0100af2 <parse+0xf>
        }
        if (*buf == '\0') {
c0100b25:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b28:	0f b6 00             	movzbl (%eax),%eax
c0100b2b:	84 c0                	test   %al,%al
c0100b2d:	74 65                	je     c0100b94 <parse+0xb1>
            break;
        }

        // save and scan past next arg
        if (argc == MAXARGS - 1) {
c0100b2f:	83 7d f4 0f          	cmpl   $0xf,-0xc(%ebp)
c0100b33:	75 14                	jne    c0100b49 <parse+0x66>
            cprintf("Too many arguments (max %d).\n", MAXARGS);
c0100b35:	c7 44 24 04 10 00 00 	movl   $0x10,0x4(%esp)
c0100b3c:	00 
c0100b3d:	c7 04 24 8d c1 10 c0 	movl   $0xc010c18d,(%esp)
c0100b44:	e8 2f f8 ff ff       	call   c0100378 <cprintf>
        }
        argv[argc ++] = buf;
c0100b49:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100b4c:	8d 50 01             	lea    0x1(%eax),%edx
c0100b4f:	89 55 f4             	mov    %edx,-0xc(%ebp)
c0100b52:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0100b59:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100b5c:	01 c2                	add    %eax,%edx
c0100b5e:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b61:	89 02                	mov    %eax,(%edx)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
c0100b63:	eb 03                	jmp    c0100b68 <parse+0x85>
            buf ++;
c0100b65:	ff 45 08             	incl   0x8(%ebp)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
c0100b68:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b6b:	0f b6 00             	movzbl (%eax),%eax
c0100b6e:	84 c0                	test   %al,%al
c0100b70:	74 8c                	je     c0100afe <parse+0x1b>
c0100b72:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b75:	0f b6 00             	movzbl (%eax),%eax
c0100b78:	0f be c0             	movsbl %al,%eax
c0100b7b:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100b7f:	c7 04 24 88 c1 10 c0 	movl   $0xc010c188,(%esp)
c0100b86:	e8 aa b0 00 00       	call   c010bc35 <strchr>
c0100b8b:	85 c0                	test   %eax,%eax
c0100b8d:	74 d6                	je     c0100b65 <parse+0x82>
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c0100b8f:	e9 6a ff ff ff       	jmp    c0100afe <parse+0x1b>
            break;
c0100b94:	90                   	nop
        }
    }
    return argc;
c0100b95:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0100b98:	89 ec                	mov    %ebp,%esp
c0100b9a:	5d                   	pop    %ebp
c0100b9b:	c3                   	ret    

c0100b9c <runcmd>:
/* *
 * runcmd - parse the input string, split it into separated arguments
 * and then lookup and invoke some related commands/
 * */
static int
runcmd(char *buf, struct trapframe *tf) {
c0100b9c:	55                   	push   %ebp
c0100b9d:	89 e5                	mov    %esp,%ebp
c0100b9f:	83 ec 68             	sub    $0x68,%esp
c0100ba2:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    char *argv[MAXARGS];
    int argc = parse(buf, argv);
c0100ba5:	8d 45 b0             	lea    -0x50(%ebp),%eax
c0100ba8:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100bac:	8b 45 08             	mov    0x8(%ebp),%eax
c0100baf:	89 04 24             	mov    %eax,(%esp)
c0100bb2:	e8 2c ff ff ff       	call   c0100ae3 <parse>
c0100bb7:	89 45 f0             	mov    %eax,-0x10(%ebp)
    if (argc == 0) {
c0100bba:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0100bbe:	75 0a                	jne    c0100bca <runcmd+0x2e>
        return 0;
c0100bc0:	b8 00 00 00 00       	mov    $0x0,%eax
c0100bc5:	e9 83 00 00 00       	jmp    c0100c4d <runcmd+0xb1>
    }
    int i;
    for (i = 0; i < NCOMMANDS; i ++) {
c0100bca:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0100bd1:	eb 5a                	jmp    c0100c2d <runcmd+0x91>
        if (strcmp(commands[i].name, argv[0]) == 0) {
c0100bd3:	8b 55 b0             	mov    -0x50(%ebp),%edx
c0100bd6:	8b 4d f4             	mov    -0xc(%ebp),%ecx
c0100bd9:	89 c8                	mov    %ecx,%eax
c0100bdb:	01 c0                	add    %eax,%eax
c0100bdd:	01 c8                	add    %ecx,%eax
c0100bdf:	c1 e0 02             	shl    $0x2,%eax
c0100be2:	05 00 f0 12 c0       	add    $0xc012f000,%eax
c0100be7:	8b 00                	mov    (%eax),%eax
c0100be9:	89 54 24 04          	mov    %edx,0x4(%esp)
c0100bed:	89 04 24             	mov    %eax,(%esp)
c0100bf0:	e8 a4 af 00 00       	call   c010bb99 <strcmp>
c0100bf5:	85 c0                	test   %eax,%eax
c0100bf7:	75 31                	jne    c0100c2a <runcmd+0x8e>
            return commands[i].func(argc - 1, argv + 1, tf);
c0100bf9:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0100bfc:	89 d0                	mov    %edx,%eax
c0100bfe:	01 c0                	add    %eax,%eax
c0100c00:	01 d0                	add    %edx,%eax
c0100c02:	c1 e0 02             	shl    $0x2,%eax
c0100c05:	05 08 f0 12 c0       	add    $0xc012f008,%eax
c0100c0a:	8b 10                	mov    (%eax),%edx
c0100c0c:	8d 45 b0             	lea    -0x50(%ebp),%eax
c0100c0f:	83 c0 04             	add    $0x4,%eax
c0100c12:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c0100c15:	8d 59 ff             	lea    -0x1(%ecx),%ebx
c0100c18:	8b 4d 0c             	mov    0xc(%ebp),%ecx
c0100c1b:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0100c1f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100c23:	89 1c 24             	mov    %ebx,(%esp)
c0100c26:	ff d2                	call   *%edx
c0100c28:	eb 23                	jmp    c0100c4d <runcmd+0xb1>
    for (i = 0; i < NCOMMANDS; i ++) {
c0100c2a:	ff 45 f4             	incl   -0xc(%ebp)
c0100c2d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100c30:	83 f8 02             	cmp    $0x2,%eax
c0100c33:	76 9e                	jbe    c0100bd3 <runcmd+0x37>
        }
    }
    cprintf("Unknown command '%s'\n", argv[0]);
c0100c35:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0100c38:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100c3c:	c7 04 24 ab c1 10 c0 	movl   $0xc010c1ab,(%esp)
c0100c43:	e8 30 f7 ff ff       	call   c0100378 <cprintf>
    return 0;
c0100c48:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100c4d:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c0100c50:	89 ec                	mov    %ebp,%esp
c0100c52:	5d                   	pop    %ebp
c0100c53:	c3                   	ret    

c0100c54 <kmonitor>:

/***** Implementations of basic kernel monitor commands *****/

void
kmonitor(struct trapframe *tf) {
c0100c54:	55                   	push   %ebp
c0100c55:	89 e5                	mov    %esp,%ebp
c0100c57:	83 ec 28             	sub    $0x28,%esp
    cprintf("Welcome to the kernel debug monitor!!\n");
c0100c5a:	c7 04 24 c4 c1 10 c0 	movl   $0xc010c1c4,(%esp)
c0100c61:	e8 12 f7 ff ff       	call   c0100378 <cprintf>
    cprintf("Type 'help' for a list of commands.\n");
c0100c66:	c7 04 24 ec c1 10 c0 	movl   $0xc010c1ec,(%esp)
c0100c6d:	e8 06 f7 ff ff       	call   c0100378 <cprintf>

    if (tf != NULL) {
c0100c72:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0100c76:	74 0b                	je     c0100c83 <kmonitor+0x2f>
        print_trapframe(tf);
c0100c78:	8b 45 08             	mov    0x8(%ebp),%eax
c0100c7b:	89 04 24             	mov    %eax,(%esp)
c0100c7e:	e8 2a 17 00 00       	call   c01023ad <print_trapframe>
    }

    char *buf;
    while (1) {
        if ((buf = readline("K> ")) != NULL) {
c0100c83:	c7 04 24 11 c2 10 c0 	movl   $0xc010c211,(%esp)
c0100c8a:	e8 da f5 ff ff       	call   c0100269 <readline>
c0100c8f:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0100c92:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0100c96:	74 eb                	je     c0100c83 <kmonitor+0x2f>
            if (runcmd(buf, tf) < 0) {
c0100c98:	8b 45 08             	mov    0x8(%ebp),%eax
c0100c9b:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100c9f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100ca2:	89 04 24             	mov    %eax,(%esp)
c0100ca5:	e8 f2 fe ff ff       	call   c0100b9c <runcmd>
c0100caa:	85 c0                	test   %eax,%eax
c0100cac:	78 02                	js     c0100cb0 <kmonitor+0x5c>
        if ((buf = readline("K> ")) != NULL) {
c0100cae:	eb d3                	jmp    c0100c83 <kmonitor+0x2f>
                break;
c0100cb0:	90                   	nop
            }
        }
    }
}
c0100cb1:	90                   	nop
c0100cb2:	89 ec                	mov    %ebp,%esp
c0100cb4:	5d                   	pop    %ebp
c0100cb5:	c3                   	ret    

c0100cb6 <mon_help>:

/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
c0100cb6:	55                   	push   %ebp
c0100cb7:	89 e5                	mov    %esp,%ebp
c0100cb9:	83 ec 28             	sub    $0x28,%esp
    int i;
    for (i = 0; i < NCOMMANDS; i ++) {
c0100cbc:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0100cc3:	eb 3d                	jmp    c0100d02 <mon_help+0x4c>
        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
c0100cc5:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0100cc8:	89 d0                	mov    %edx,%eax
c0100cca:	01 c0                	add    %eax,%eax
c0100ccc:	01 d0                	add    %edx,%eax
c0100cce:	c1 e0 02             	shl    $0x2,%eax
c0100cd1:	05 04 f0 12 c0       	add    $0xc012f004,%eax
c0100cd6:	8b 10                	mov    (%eax),%edx
c0100cd8:	8b 4d f4             	mov    -0xc(%ebp),%ecx
c0100cdb:	89 c8                	mov    %ecx,%eax
c0100cdd:	01 c0                	add    %eax,%eax
c0100cdf:	01 c8                	add    %ecx,%eax
c0100ce1:	c1 e0 02             	shl    $0x2,%eax
c0100ce4:	05 00 f0 12 c0       	add    $0xc012f000,%eax
c0100ce9:	8b 00                	mov    (%eax),%eax
c0100ceb:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100cef:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100cf3:	c7 04 24 15 c2 10 c0 	movl   $0xc010c215,(%esp)
c0100cfa:	e8 79 f6 ff ff       	call   c0100378 <cprintf>
    for (i = 0; i < NCOMMANDS; i ++) {
c0100cff:	ff 45 f4             	incl   -0xc(%ebp)
c0100d02:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100d05:	83 f8 02             	cmp    $0x2,%eax
c0100d08:	76 bb                	jbe    c0100cc5 <mon_help+0xf>
    }
    return 0;
c0100d0a:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100d0f:	89 ec                	mov    %ebp,%esp
c0100d11:	5d                   	pop    %ebp
c0100d12:	c3                   	ret    

c0100d13 <mon_kerninfo>:
/* *
 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 * print the memory occupancy in kernel.
 * */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
c0100d13:	55                   	push   %ebp
c0100d14:	89 e5                	mov    %esp,%ebp
c0100d16:	83 ec 08             	sub    $0x8,%esp
    print_kerninfo();
c0100d19:	e8 73 fc ff ff       	call   c0100991 <print_kerninfo>
    return 0;
c0100d1e:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100d23:	89 ec                	mov    %ebp,%esp
c0100d25:	5d                   	pop    %ebp
c0100d26:	c3                   	ret    

c0100d27 <mon_backtrace>:
/* *
 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 * print a backtrace of the stack.
 * */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
c0100d27:	55                   	push   %ebp
c0100d28:	89 e5                	mov    %esp,%ebp
c0100d2a:	83 ec 08             	sub    $0x8,%esp
    print_stackframe();
c0100d2d:	e8 ab fd ff ff       	call   c0100add <print_stackframe>
    return 0;
c0100d32:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100d37:	89 ec                	mov    %ebp,%esp
c0100d39:	5d                   	pop    %ebp
c0100d3a:	c3                   	ret    

c0100d3b <__panic>:
/* *
 * __panic - __panic is called on unresolvable fatal errors. it prints
 * "panic: 'message'", and then enters the kernel monitor.
 * */
void
__panic(const char *file, int line, const char *fmt, ...) {
c0100d3b:	55                   	push   %ebp
c0100d3c:	89 e5                	mov    %esp,%ebp
c0100d3e:	83 ec 28             	sub    $0x28,%esp
    if (is_panic) {
c0100d41:	a1 20 34 1a c0       	mov    0xc01a3420,%eax
c0100d46:	85 c0                	test   %eax,%eax
c0100d48:	75 5b                	jne    c0100da5 <__panic+0x6a>
        goto panic_dead;
    }
    is_panic = 1;
c0100d4a:	c7 05 20 34 1a c0 01 	movl   $0x1,0xc01a3420
c0100d51:	00 00 00 

    // print the 'message'
    va_list ap;
    va_start(ap, fmt);
c0100d54:	8d 45 14             	lea    0x14(%ebp),%eax
c0100d57:	89 45 f4             	mov    %eax,-0xc(%ebp)
    cprintf("kernel panic at %s:%d:\n    ", file, line);
c0100d5a:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100d5d:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100d61:	8b 45 08             	mov    0x8(%ebp),%eax
c0100d64:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100d68:	c7 04 24 1e c2 10 c0 	movl   $0xc010c21e,(%esp)
c0100d6f:	e8 04 f6 ff ff       	call   c0100378 <cprintf>
    vcprintf(fmt, ap);
c0100d74:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100d77:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100d7b:	8b 45 10             	mov    0x10(%ebp),%eax
c0100d7e:	89 04 24             	mov    %eax,(%esp)
c0100d81:	e8 bd f5 ff ff       	call   c0100343 <vcprintf>
    cprintf("\n");
c0100d86:	c7 04 24 3a c2 10 c0 	movl   $0xc010c23a,(%esp)
c0100d8d:	e8 e6 f5 ff ff       	call   c0100378 <cprintf>
    
    cprintf("stack trackback:\n");
c0100d92:	c7 04 24 3c c2 10 c0 	movl   $0xc010c23c,(%esp)
c0100d99:	e8 da f5 ff ff       	call   c0100378 <cprintf>
    print_stackframe();
c0100d9e:	e8 3a fd ff ff       	call   c0100add <print_stackframe>
c0100da3:	eb 01                	jmp    c0100da6 <__panic+0x6b>
        goto panic_dead;
c0100da5:	90                   	nop
    
    va_end(ap);

panic_dead:
    intr_disable();
c0100da6:	e8 46 12 00 00       	call   c0101ff1 <intr_disable>
    while (1) {
        kmonitor(NULL);
c0100dab:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0100db2:	e8 9d fe ff ff       	call   c0100c54 <kmonitor>
c0100db7:	eb f2                	jmp    c0100dab <__panic+0x70>

c0100db9 <__warn>:
    }
}

/* __warn - like panic, but don't */
void
__warn(const char *file, int line, const char *fmt, ...) {
c0100db9:	55                   	push   %ebp
c0100dba:	89 e5                	mov    %esp,%ebp
c0100dbc:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    va_start(ap, fmt);
c0100dbf:	8d 45 14             	lea    0x14(%ebp),%eax
c0100dc2:	89 45 f4             	mov    %eax,-0xc(%ebp)
    cprintf("kernel warning at %s:%d:\n    ", file, line);
c0100dc5:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100dc8:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100dcc:	8b 45 08             	mov    0x8(%ebp),%eax
c0100dcf:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100dd3:	c7 04 24 4e c2 10 c0 	movl   $0xc010c24e,(%esp)
c0100dda:	e8 99 f5 ff ff       	call   c0100378 <cprintf>
    vcprintf(fmt, ap);
c0100ddf:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100de2:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100de6:	8b 45 10             	mov    0x10(%ebp),%eax
c0100de9:	89 04 24             	mov    %eax,(%esp)
c0100dec:	e8 52 f5 ff ff       	call   c0100343 <vcprintf>
    cprintf("\n");
c0100df1:	c7 04 24 3a c2 10 c0 	movl   $0xc010c23a,(%esp)
c0100df8:	e8 7b f5 ff ff       	call   c0100378 <cprintf>
    va_end(ap);
}
c0100dfd:	90                   	nop
c0100dfe:	89 ec                	mov    %ebp,%esp
c0100e00:	5d                   	pop    %ebp
c0100e01:	c3                   	ret    

c0100e02 <is_kernel_panic>:

bool
is_kernel_panic(void) {
c0100e02:	55                   	push   %ebp
c0100e03:	89 e5                	mov    %esp,%ebp
    return is_panic;
c0100e05:	a1 20 34 1a c0       	mov    0xc01a3420,%eax
}
c0100e0a:	5d                   	pop    %ebp
c0100e0b:	c3                   	ret    

c0100e0c <clock_init>:
/* *
 * clock_init - initialize 8253 clock to interrupt 100 times per second,
 * and then enable IRQ_TIMER.
 * */
void
clock_init(void) {
c0100e0c:	55                   	push   %ebp
c0100e0d:	89 e5                	mov    %esp,%ebp
c0100e0f:	83 ec 28             	sub    $0x28,%esp
c0100e12:	66 c7 45 ee 43 00    	movw   $0x43,-0x12(%ebp)
c0100e18:	c6 45 ed 34          	movb   $0x34,-0x13(%ebp)
        : "memory", "cc");
}

static inline void
outb(uint16_t port, uint8_t data) {
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100e1c:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0100e20:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0100e24:	ee                   	out    %al,(%dx)
}
c0100e25:	90                   	nop
c0100e26:	66 c7 45 f2 40 00    	movw   $0x40,-0xe(%ebp)
c0100e2c:	c6 45 f1 9c          	movb   $0x9c,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100e30:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0100e34:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0100e38:	ee                   	out    %al,(%dx)
}
c0100e39:	90                   	nop
c0100e3a:	66 c7 45 f6 40 00    	movw   $0x40,-0xa(%ebp)
c0100e40:	c6 45 f5 2e          	movb   $0x2e,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100e44:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c0100e48:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0100e4c:	ee                   	out    %al,(%dx)
}
c0100e4d:	90                   	nop
    outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
    outb(IO_TIMER1, TIMER_DIV(100) % 256);
    outb(IO_TIMER1, TIMER_DIV(100) / 256);

    // initialize time counter 'ticks' to zero
    ticks = 0;
c0100e4e:	c7 05 24 34 1a c0 00 	movl   $0x0,0xc01a3424
c0100e55:	00 00 00 

    cprintf("++ setup timer interrupts\n");
c0100e58:	c7 04 24 6c c2 10 c0 	movl   $0xc010c26c,(%esp)
c0100e5f:	e8 14 f5 ff ff       	call   c0100378 <cprintf>
    pic_enable(IRQ_TIMER);
c0100e64:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0100e6b:	e8 e6 11 00 00       	call   c0102056 <pic_enable>
}
c0100e70:	90                   	nop
c0100e71:	89 ec                	mov    %ebp,%esp
c0100e73:	5d                   	pop    %ebp
c0100e74:	c3                   	ret    

c0100e75 <__intr_save>:
#include <assert.h>
#include <atomic.h>
#include <sched.h>

static inline bool
__intr_save(void) {
c0100e75:	55                   	push   %ebp
c0100e76:	89 e5                	mov    %esp,%ebp
c0100e78:	83 ec 18             	sub    $0x18,%esp
}

static inline uint32_t
read_eflags(void) {
    uint32_t eflags;
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c0100e7b:	9c                   	pushf  
c0100e7c:	58                   	pop    %eax
c0100e7d:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c0100e80:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c0100e83:	25 00 02 00 00       	and    $0x200,%eax
c0100e88:	85 c0                	test   %eax,%eax
c0100e8a:	74 0c                	je     c0100e98 <__intr_save+0x23>
        intr_disable();
c0100e8c:	e8 60 11 00 00       	call   c0101ff1 <intr_disable>
        return 1;
c0100e91:	b8 01 00 00 00       	mov    $0x1,%eax
c0100e96:	eb 05                	jmp    c0100e9d <__intr_save+0x28>
    }
    return 0;
c0100e98:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100e9d:	89 ec                	mov    %ebp,%esp
c0100e9f:	5d                   	pop    %ebp
c0100ea0:	c3                   	ret    

c0100ea1 <__intr_restore>:

static inline void
__intr_restore(bool flag) {
c0100ea1:	55                   	push   %ebp
c0100ea2:	89 e5                	mov    %esp,%ebp
c0100ea4:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c0100ea7:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0100eab:	74 05                	je     c0100eb2 <__intr_restore+0x11>
        intr_enable();
c0100ead:	e8 37 11 00 00       	call   c0101fe9 <intr_enable>
    }
}
c0100eb2:	90                   	nop
c0100eb3:	89 ec                	mov    %ebp,%esp
c0100eb5:	5d                   	pop    %ebp
c0100eb6:	c3                   	ret    

c0100eb7 <delay>:
#include <memlayout.h>
#include <sync.h>

/* stupid I/O delay routine necessitated by historical PC design flaws */
static void
delay(void) {
c0100eb7:	55                   	push   %ebp
c0100eb8:	89 e5                	mov    %esp,%ebp
c0100eba:	83 ec 10             	sub    $0x10,%esp
c0100ebd:	66 c7 45 f2 84 00    	movw   $0x84,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100ec3:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0100ec7:	89 c2                	mov    %eax,%edx
c0100ec9:	ec                   	in     (%dx),%al
c0100eca:	88 45 f1             	mov    %al,-0xf(%ebp)
c0100ecd:	66 c7 45 f6 84 00    	movw   $0x84,-0xa(%ebp)
c0100ed3:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0100ed7:	89 c2                	mov    %eax,%edx
c0100ed9:	ec                   	in     (%dx),%al
c0100eda:	88 45 f5             	mov    %al,-0xb(%ebp)
c0100edd:	66 c7 45 fa 84 00    	movw   $0x84,-0x6(%ebp)
c0100ee3:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c0100ee7:	89 c2                	mov    %eax,%edx
c0100ee9:	ec                   	in     (%dx),%al
c0100eea:	88 45 f9             	mov    %al,-0x7(%ebp)
c0100eed:	66 c7 45 fe 84 00    	movw   $0x84,-0x2(%ebp)
c0100ef3:	0f b7 45 fe          	movzwl -0x2(%ebp),%eax
c0100ef7:	89 c2                	mov    %eax,%edx
c0100ef9:	ec                   	in     (%dx),%al
c0100efa:	88 45 fd             	mov    %al,-0x3(%ebp)
    inb(0x84);
    inb(0x84);
    inb(0x84);
    inb(0x84);
}
c0100efd:	90                   	nop
c0100efe:	89 ec                	mov    %ebp,%esp
c0100f00:	5d                   	pop    %ebp
c0100f01:	c3                   	ret    

c0100f02 <cga_init>:
static uint16_t addr_6845;

/* TEXT-mode CGA/VGA display output */

static void
cga_init(void) {
c0100f02:	55                   	push   %ebp
c0100f03:	89 e5                	mov    %esp,%ebp
c0100f05:	83 ec 20             	sub    $0x20,%esp
    volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE);
c0100f08:	c7 45 fc 00 80 0b c0 	movl   $0xc00b8000,-0x4(%ebp)
    uint16_t was = *cp;
c0100f0f:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100f12:	0f b7 00             	movzwl (%eax),%eax
c0100f15:	66 89 45 fa          	mov    %ax,-0x6(%ebp)
    *cp = (uint16_t) 0xA55A;
c0100f19:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100f1c:	66 c7 00 5a a5       	movw   $0xa55a,(%eax)
    if (*cp != 0xA55A) {
c0100f21:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100f24:	0f b7 00             	movzwl (%eax),%eax
c0100f27:	0f b7 c0             	movzwl %ax,%eax
c0100f2a:	3d 5a a5 00 00       	cmp    $0xa55a,%eax
c0100f2f:	74 12                	je     c0100f43 <cga_init+0x41>
        cp = (uint16_t*)(MONO_BUF + KERNBASE);
c0100f31:	c7 45 fc 00 00 0b c0 	movl   $0xc00b0000,-0x4(%ebp)
        addr_6845 = MONO_BASE;
c0100f38:	66 c7 05 46 34 1a c0 	movw   $0x3b4,0xc01a3446
c0100f3f:	b4 03 
c0100f41:	eb 13                	jmp    c0100f56 <cga_init+0x54>
    } else {
        *cp = was;
c0100f43:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100f46:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c0100f4a:	66 89 10             	mov    %dx,(%eax)
        addr_6845 = CGA_BASE;
c0100f4d:	66 c7 05 46 34 1a c0 	movw   $0x3d4,0xc01a3446
c0100f54:	d4 03 
    }

    // Extract cursor location
    uint32_t pos;
    outb(addr_6845, 14);
c0100f56:	0f b7 05 46 34 1a c0 	movzwl 0xc01a3446,%eax
c0100f5d:	66 89 45 e6          	mov    %ax,-0x1a(%ebp)
c0100f61:	c6 45 e5 0e          	movb   $0xe,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100f65:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0100f69:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0100f6d:	ee                   	out    %al,(%dx)
}
c0100f6e:	90                   	nop
    pos = inb(addr_6845 + 1) << 8;
c0100f6f:	0f b7 05 46 34 1a c0 	movzwl 0xc01a3446,%eax
c0100f76:	40                   	inc    %eax
c0100f77:	0f b7 c0             	movzwl %ax,%eax
c0100f7a:	66 89 45 ea          	mov    %ax,-0x16(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100f7e:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100f82:	89 c2                	mov    %eax,%edx
c0100f84:	ec                   	in     (%dx),%al
c0100f85:	88 45 e9             	mov    %al,-0x17(%ebp)
    return data;
c0100f88:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0100f8c:	0f b6 c0             	movzbl %al,%eax
c0100f8f:	c1 e0 08             	shl    $0x8,%eax
c0100f92:	89 45 f4             	mov    %eax,-0xc(%ebp)
    outb(addr_6845, 15);
c0100f95:	0f b7 05 46 34 1a c0 	movzwl 0xc01a3446,%eax
c0100f9c:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0100fa0:	c6 45 ed 0f          	movb   $0xf,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100fa4:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0100fa8:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0100fac:	ee                   	out    %al,(%dx)
}
c0100fad:	90                   	nop
    pos |= inb(addr_6845 + 1);
c0100fae:	0f b7 05 46 34 1a c0 	movzwl 0xc01a3446,%eax
c0100fb5:	40                   	inc    %eax
c0100fb6:	0f b7 c0             	movzwl %ax,%eax
c0100fb9:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100fbd:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0100fc1:	89 c2                	mov    %eax,%edx
c0100fc3:	ec                   	in     (%dx),%al
c0100fc4:	88 45 f1             	mov    %al,-0xf(%ebp)
    return data;
c0100fc7:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0100fcb:	0f b6 c0             	movzbl %al,%eax
c0100fce:	09 45 f4             	or     %eax,-0xc(%ebp)

    crt_buf = (uint16_t*) cp;
c0100fd1:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100fd4:	a3 40 34 1a c0       	mov    %eax,0xc01a3440
    crt_pos = pos;
c0100fd9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100fdc:	0f b7 c0             	movzwl %ax,%eax
c0100fdf:	66 a3 44 34 1a c0    	mov    %ax,0xc01a3444
}
c0100fe5:	90                   	nop
c0100fe6:	89 ec                	mov    %ebp,%esp
c0100fe8:	5d                   	pop    %ebp
c0100fe9:	c3                   	ret    

c0100fea <serial_init>:

static bool serial_exists = 0;

static void
serial_init(void) {
c0100fea:	55                   	push   %ebp
c0100feb:	89 e5                	mov    %esp,%ebp
c0100fed:	83 ec 48             	sub    $0x48,%esp
c0100ff0:	66 c7 45 d2 fa 03    	movw   $0x3fa,-0x2e(%ebp)
c0100ff6:	c6 45 d1 00          	movb   $0x0,-0x2f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100ffa:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c0100ffe:	0f b7 55 d2          	movzwl -0x2e(%ebp),%edx
c0101002:	ee                   	out    %al,(%dx)
}
c0101003:	90                   	nop
c0101004:	66 c7 45 d6 fb 03    	movw   $0x3fb,-0x2a(%ebp)
c010100a:	c6 45 d5 80          	movb   $0x80,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010100e:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0101012:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0101016:	ee                   	out    %al,(%dx)
}
c0101017:	90                   	nop
c0101018:	66 c7 45 da f8 03    	movw   $0x3f8,-0x26(%ebp)
c010101e:	c6 45 d9 0c          	movb   $0xc,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101022:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0101026:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c010102a:	ee                   	out    %al,(%dx)
}
c010102b:	90                   	nop
c010102c:	66 c7 45 de f9 03    	movw   $0x3f9,-0x22(%ebp)
c0101032:	c6 45 dd 00          	movb   $0x0,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101036:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c010103a:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c010103e:	ee                   	out    %al,(%dx)
}
c010103f:	90                   	nop
c0101040:	66 c7 45 e2 fb 03    	movw   $0x3fb,-0x1e(%ebp)
c0101046:	c6 45 e1 03          	movb   $0x3,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010104a:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c010104e:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c0101052:	ee                   	out    %al,(%dx)
}
c0101053:	90                   	nop
c0101054:	66 c7 45 e6 fc 03    	movw   $0x3fc,-0x1a(%ebp)
c010105a:	c6 45 e5 00          	movb   $0x0,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010105e:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101062:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101066:	ee                   	out    %al,(%dx)
}
c0101067:	90                   	nop
c0101068:	66 c7 45 ea f9 03    	movw   $0x3f9,-0x16(%ebp)
c010106e:	c6 45 e9 01          	movb   $0x1,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101072:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0101076:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c010107a:	ee                   	out    %al,(%dx)
}
c010107b:	90                   	nop
c010107c:	66 c7 45 ee fd 03    	movw   $0x3fd,-0x12(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101082:	0f b7 45 ee          	movzwl -0x12(%ebp),%eax
c0101086:	89 c2                	mov    %eax,%edx
c0101088:	ec                   	in     (%dx),%al
c0101089:	88 45 ed             	mov    %al,-0x13(%ebp)
    return data;
c010108c:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
    // Enable rcv interrupts
    outb(COM1 + COM_IER, COM_IER_RDI);

    // Clear any preexisting overrun indications and interrupts
    // Serial port doesn't exist if COM_LSR returns 0xFF
    serial_exists = (inb(COM1 + COM_LSR) != 0xFF);
c0101090:	3c ff                	cmp    $0xff,%al
c0101092:	0f 95 c0             	setne  %al
c0101095:	0f b6 c0             	movzbl %al,%eax
c0101098:	a3 48 34 1a c0       	mov    %eax,0xc01a3448
c010109d:	66 c7 45 f2 fa 03    	movw   $0x3fa,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01010a3:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c01010a7:	89 c2                	mov    %eax,%edx
c01010a9:	ec                   	in     (%dx),%al
c01010aa:	88 45 f1             	mov    %al,-0xf(%ebp)
c01010ad:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
c01010b3:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c01010b7:	89 c2                	mov    %eax,%edx
c01010b9:	ec                   	in     (%dx),%al
c01010ba:	88 45 f5             	mov    %al,-0xb(%ebp)
    (void) inb(COM1+COM_IIR);
    (void) inb(COM1+COM_RX);

    if (serial_exists) {
c01010bd:	a1 48 34 1a c0       	mov    0xc01a3448,%eax
c01010c2:	85 c0                	test   %eax,%eax
c01010c4:	74 0c                	je     c01010d2 <serial_init+0xe8>
        pic_enable(IRQ_COM1);
c01010c6:	c7 04 24 04 00 00 00 	movl   $0x4,(%esp)
c01010cd:	e8 84 0f 00 00       	call   c0102056 <pic_enable>
    }
}
c01010d2:	90                   	nop
c01010d3:	89 ec                	mov    %ebp,%esp
c01010d5:	5d                   	pop    %ebp
c01010d6:	c3                   	ret    

c01010d7 <lpt_putc_sub>:

static void
lpt_putc_sub(int c) {
c01010d7:	55                   	push   %ebp
c01010d8:	89 e5                	mov    %esp,%ebp
c01010da:	83 ec 20             	sub    $0x20,%esp
    int i;
    for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {
c01010dd:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c01010e4:	eb 08                	jmp    c01010ee <lpt_putc_sub+0x17>
        delay();
c01010e6:	e8 cc fd ff ff       	call   c0100eb7 <delay>
    for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {
c01010eb:	ff 45 fc             	incl   -0x4(%ebp)
c01010ee:	66 c7 45 fa 79 03    	movw   $0x379,-0x6(%ebp)
c01010f4:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c01010f8:	89 c2                	mov    %eax,%edx
c01010fa:	ec                   	in     (%dx),%al
c01010fb:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c01010fe:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c0101102:	84 c0                	test   %al,%al
c0101104:	78 09                	js     c010110f <lpt_putc_sub+0x38>
c0101106:	81 7d fc ff 31 00 00 	cmpl   $0x31ff,-0x4(%ebp)
c010110d:	7e d7                	jle    c01010e6 <lpt_putc_sub+0xf>
    }
    outb(LPTPORT + 0, c);
c010110f:	8b 45 08             	mov    0x8(%ebp),%eax
c0101112:	0f b6 c0             	movzbl %al,%eax
c0101115:	66 c7 45 ee 78 03    	movw   $0x378,-0x12(%ebp)
c010111b:	88 45 ed             	mov    %al,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010111e:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101122:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101126:	ee                   	out    %al,(%dx)
}
c0101127:	90                   	nop
c0101128:	66 c7 45 f2 7a 03    	movw   $0x37a,-0xe(%ebp)
c010112e:	c6 45 f1 0d          	movb   $0xd,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101132:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0101136:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c010113a:	ee                   	out    %al,(%dx)
}
c010113b:	90                   	nop
c010113c:	66 c7 45 f6 7a 03    	movw   $0x37a,-0xa(%ebp)
c0101142:	c6 45 f5 08          	movb   $0x8,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101146:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c010114a:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c010114e:	ee                   	out    %al,(%dx)
}
c010114f:	90                   	nop
    outb(LPTPORT + 2, 0x08 | 0x04 | 0x01);
    outb(LPTPORT + 2, 0x08);
}
c0101150:	90                   	nop
c0101151:	89 ec                	mov    %ebp,%esp
c0101153:	5d                   	pop    %ebp
c0101154:	c3                   	ret    

c0101155 <lpt_putc>:

/* lpt_putc - copy console output to parallel port */
static void
lpt_putc(int c) {
c0101155:	55                   	push   %ebp
c0101156:	89 e5                	mov    %esp,%ebp
c0101158:	83 ec 04             	sub    $0x4,%esp
    if (c != '\b') {
c010115b:	83 7d 08 08          	cmpl   $0x8,0x8(%ebp)
c010115f:	74 0d                	je     c010116e <lpt_putc+0x19>
        lpt_putc_sub(c);
c0101161:	8b 45 08             	mov    0x8(%ebp),%eax
c0101164:	89 04 24             	mov    %eax,(%esp)
c0101167:	e8 6b ff ff ff       	call   c01010d7 <lpt_putc_sub>
    else {
        lpt_putc_sub('\b');
        lpt_putc_sub(' ');
        lpt_putc_sub('\b');
    }
}
c010116c:	eb 24                	jmp    c0101192 <lpt_putc+0x3d>
        lpt_putc_sub('\b');
c010116e:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c0101175:	e8 5d ff ff ff       	call   c01010d7 <lpt_putc_sub>
        lpt_putc_sub(' ');
c010117a:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c0101181:	e8 51 ff ff ff       	call   c01010d7 <lpt_putc_sub>
        lpt_putc_sub('\b');
c0101186:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c010118d:	e8 45 ff ff ff       	call   c01010d7 <lpt_putc_sub>
}
c0101192:	90                   	nop
c0101193:	89 ec                	mov    %ebp,%esp
c0101195:	5d                   	pop    %ebp
c0101196:	c3                   	ret    

c0101197 <cga_putc>:

/* cga_putc - print character to console */
static void
cga_putc(int c) {
c0101197:	55                   	push   %ebp
c0101198:	89 e5                	mov    %esp,%ebp
c010119a:	83 ec 38             	sub    $0x38,%esp
c010119d:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    // set black on white
    if (!(c & ~0xFF)) {
c01011a0:	8b 45 08             	mov    0x8(%ebp),%eax
c01011a3:	25 00 ff ff ff       	and    $0xffffff00,%eax
c01011a8:	85 c0                	test   %eax,%eax
c01011aa:	75 07                	jne    c01011b3 <cga_putc+0x1c>
        c |= 0x0700;
c01011ac:	81 4d 08 00 07 00 00 	orl    $0x700,0x8(%ebp)
    }

    switch (c & 0xff) {
c01011b3:	8b 45 08             	mov    0x8(%ebp),%eax
c01011b6:	0f b6 c0             	movzbl %al,%eax
c01011b9:	83 f8 0d             	cmp    $0xd,%eax
c01011bc:	74 72                	je     c0101230 <cga_putc+0x99>
c01011be:	83 f8 0d             	cmp    $0xd,%eax
c01011c1:	0f 8f a3 00 00 00    	jg     c010126a <cga_putc+0xd3>
c01011c7:	83 f8 08             	cmp    $0x8,%eax
c01011ca:	74 0a                	je     c01011d6 <cga_putc+0x3f>
c01011cc:	83 f8 0a             	cmp    $0xa,%eax
c01011cf:	74 4c                	je     c010121d <cga_putc+0x86>
c01011d1:	e9 94 00 00 00       	jmp    c010126a <cga_putc+0xd3>
    case '\b':
        if (crt_pos > 0) {
c01011d6:	0f b7 05 44 34 1a c0 	movzwl 0xc01a3444,%eax
c01011dd:	85 c0                	test   %eax,%eax
c01011df:	0f 84 af 00 00 00    	je     c0101294 <cga_putc+0xfd>
            crt_pos --;
c01011e5:	0f b7 05 44 34 1a c0 	movzwl 0xc01a3444,%eax
c01011ec:	48                   	dec    %eax
c01011ed:	0f b7 c0             	movzwl %ax,%eax
c01011f0:	66 a3 44 34 1a c0    	mov    %ax,0xc01a3444
            crt_buf[crt_pos] = (c & ~0xff) | ' ';
c01011f6:	8b 45 08             	mov    0x8(%ebp),%eax
c01011f9:	98                   	cwtl   
c01011fa:	25 00 ff ff ff       	and    $0xffffff00,%eax
c01011ff:	98                   	cwtl   
c0101200:	83 c8 20             	or     $0x20,%eax
c0101203:	98                   	cwtl   
c0101204:	8b 0d 40 34 1a c0    	mov    0xc01a3440,%ecx
c010120a:	0f b7 15 44 34 1a c0 	movzwl 0xc01a3444,%edx
c0101211:	01 d2                	add    %edx,%edx
c0101213:	01 ca                	add    %ecx,%edx
c0101215:	0f b7 c0             	movzwl %ax,%eax
c0101218:	66 89 02             	mov    %ax,(%edx)
        }
        break;
c010121b:	eb 77                	jmp    c0101294 <cga_putc+0xfd>
    case '\n':
        crt_pos += CRT_COLS;
c010121d:	0f b7 05 44 34 1a c0 	movzwl 0xc01a3444,%eax
c0101224:	83 c0 50             	add    $0x50,%eax
c0101227:	0f b7 c0             	movzwl %ax,%eax
c010122a:	66 a3 44 34 1a c0    	mov    %ax,0xc01a3444
    case '\r':
        crt_pos -= (crt_pos % CRT_COLS);
c0101230:	0f b7 1d 44 34 1a c0 	movzwl 0xc01a3444,%ebx
c0101237:	0f b7 0d 44 34 1a c0 	movzwl 0xc01a3444,%ecx
c010123e:	ba cd cc cc cc       	mov    $0xcccccccd,%edx
c0101243:	89 c8                	mov    %ecx,%eax
c0101245:	f7 e2                	mul    %edx
c0101247:	c1 ea 06             	shr    $0x6,%edx
c010124a:	89 d0                	mov    %edx,%eax
c010124c:	c1 e0 02             	shl    $0x2,%eax
c010124f:	01 d0                	add    %edx,%eax
c0101251:	c1 e0 04             	shl    $0x4,%eax
c0101254:	29 c1                	sub    %eax,%ecx
c0101256:	89 ca                	mov    %ecx,%edx
c0101258:	0f b7 d2             	movzwl %dx,%edx
c010125b:	89 d8                	mov    %ebx,%eax
c010125d:	29 d0                	sub    %edx,%eax
c010125f:	0f b7 c0             	movzwl %ax,%eax
c0101262:	66 a3 44 34 1a c0    	mov    %ax,0xc01a3444
        break;
c0101268:	eb 2b                	jmp    c0101295 <cga_putc+0xfe>
    default:
        crt_buf[crt_pos ++] = c;     // write the character
c010126a:	8b 0d 40 34 1a c0    	mov    0xc01a3440,%ecx
c0101270:	0f b7 05 44 34 1a c0 	movzwl 0xc01a3444,%eax
c0101277:	8d 50 01             	lea    0x1(%eax),%edx
c010127a:	0f b7 d2             	movzwl %dx,%edx
c010127d:	66 89 15 44 34 1a c0 	mov    %dx,0xc01a3444
c0101284:	01 c0                	add    %eax,%eax
c0101286:	8d 14 01             	lea    (%ecx,%eax,1),%edx
c0101289:	8b 45 08             	mov    0x8(%ebp),%eax
c010128c:	0f b7 c0             	movzwl %ax,%eax
c010128f:	66 89 02             	mov    %ax,(%edx)
        break;
c0101292:	eb 01                	jmp    c0101295 <cga_putc+0xfe>
        break;
c0101294:	90                   	nop
    }

    // What is the purpose of this?
    if (crt_pos >= CRT_SIZE) {
c0101295:	0f b7 05 44 34 1a c0 	movzwl 0xc01a3444,%eax
c010129c:	3d cf 07 00 00       	cmp    $0x7cf,%eax
c01012a1:	76 5e                	jbe    c0101301 <cga_putc+0x16a>
        int i;
        memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t));
c01012a3:	a1 40 34 1a c0       	mov    0xc01a3440,%eax
c01012a8:	8d 90 a0 00 00 00    	lea    0xa0(%eax),%edx
c01012ae:	a1 40 34 1a c0       	mov    0xc01a3440,%eax
c01012b3:	c7 44 24 08 00 0f 00 	movl   $0xf00,0x8(%esp)
c01012ba:	00 
c01012bb:	89 54 24 04          	mov    %edx,0x4(%esp)
c01012bf:	89 04 24             	mov    %eax,(%esp)
c01012c2:	e8 6c ab 00 00       	call   c010be33 <memmove>
        for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) {
c01012c7:	c7 45 f4 80 07 00 00 	movl   $0x780,-0xc(%ebp)
c01012ce:	eb 15                	jmp    c01012e5 <cga_putc+0x14e>
            crt_buf[i] = 0x0700 | ' ';
c01012d0:	8b 15 40 34 1a c0    	mov    0xc01a3440,%edx
c01012d6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01012d9:	01 c0                	add    %eax,%eax
c01012db:	01 d0                	add    %edx,%eax
c01012dd:	66 c7 00 20 07       	movw   $0x720,(%eax)
        for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) {
c01012e2:	ff 45 f4             	incl   -0xc(%ebp)
c01012e5:	81 7d f4 cf 07 00 00 	cmpl   $0x7cf,-0xc(%ebp)
c01012ec:	7e e2                	jle    c01012d0 <cga_putc+0x139>
        }
        crt_pos -= CRT_COLS;
c01012ee:	0f b7 05 44 34 1a c0 	movzwl 0xc01a3444,%eax
c01012f5:	83 e8 50             	sub    $0x50,%eax
c01012f8:	0f b7 c0             	movzwl %ax,%eax
c01012fb:	66 a3 44 34 1a c0    	mov    %ax,0xc01a3444
    }

    // move that little blinky thing
    outb(addr_6845, 14);
c0101301:	0f b7 05 46 34 1a c0 	movzwl 0xc01a3446,%eax
c0101308:	66 89 45 e6          	mov    %ax,-0x1a(%ebp)
c010130c:	c6 45 e5 0e          	movb   $0xe,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101310:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101314:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101318:	ee                   	out    %al,(%dx)
}
c0101319:	90                   	nop
    outb(addr_6845 + 1, crt_pos >> 8);
c010131a:	0f b7 05 44 34 1a c0 	movzwl 0xc01a3444,%eax
c0101321:	c1 e8 08             	shr    $0x8,%eax
c0101324:	0f b7 c0             	movzwl %ax,%eax
c0101327:	0f b6 c0             	movzbl %al,%eax
c010132a:	0f b7 15 46 34 1a c0 	movzwl 0xc01a3446,%edx
c0101331:	42                   	inc    %edx
c0101332:	0f b7 d2             	movzwl %dx,%edx
c0101335:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c0101339:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010133c:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0101340:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0101344:	ee                   	out    %al,(%dx)
}
c0101345:	90                   	nop
    outb(addr_6845, 15);
c0101346:	0f b7 05 46 34 1a c0 	movzwl 0xc01a3446,%eax
c010134d:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101351:	c6 45 ed 0f          	movb   $0xf,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101355:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101359:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c010135d:	ee                   	out    %al,(%dx)
}
c010135e:	90                   	nop
    outb(addr_6845 + 1, crt_pos);
c010135f:	0f b7 05 44 34 1a c0 	movzwl 0xc01a3444,%eax
c0101366:	0f b6 c0             	movzbl %al,%eax
c0101369:	0f b7 15 46 34 1a c0 	movzwl 0xc01a3446,%edx
c0101370:	42                   	inc    %edx
c0101371:	0f b7 d2             	movzwl %dx,%edx
c0101374:	66 89 55 f2          	mov    %dx,-0xe(%ebp)
c0101378:	88 45 f1             	mov    %al,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010137b:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c010137f:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101383:	ee                   	out    %al,(%dx)
}
c0101384:	90                   	nop
}
c0101385:	90                   	nop
c0101386:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c0101389:	89 ec                	mov    %ebp,%esp
c010138b:	5d                   	pop    %ebp
c010138c:	c3                   	ret    

c010138d <serial_putc_sub>:

static void
serial_putc_sub(int c) {
c010138d:	55                   	push   %ebp
c010138e:	89 e5                	mov    %esp,%ebp
c0101390:	83 ec 10             	sub    $0x10,%esp
    int i;
    for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) {
c0101393:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c010139a:	eb 08                	jmp    c01013a4 <serial_putc_sub+0x17>
        delay();
c010139c:	e8 16 fb ff ff       	call   c0100eb7 <delay>
    for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) {
c01013a1:	ff 45 fc             	incl   -0x4(%ebp)
c01013a4:	66 c7 45 fa fd 03    	movw   $0x3fd,-0x6(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01013aa:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c01013ae:	89 c2                	mov    %eax,%edx
c01013b0:	ec                   	in     (%dx),%al
c01013b1:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c01013b4:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c01013b8:	0f b6 c0             	movzbl %al,%eax
c01013bb:	83 e0 20             	and    $0x20,%eax
c01013be:	85 c0                	test   %eax,%eax
c01013c0:	75 09                	jne    c01013cb <serial_putc_sub+0x3e>
c01013c2:	81 7d fc ff 31 00 00 	cmpl   $0x31ff,-0x4(%ebp)
c01013c9:	7e d1                	jle    c010139c <serial_putc_sub+0xf>
    }
    outb(COM1 + COM_TX, c);
c01013cb:	8b 45 08             	mov    0x8(%ebp),%eax
c01013ce:	0f b6 c0             	movzbl %al,%eax
c01013d1:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
c01013d7:	88 45 f5             	mov    %al,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01013da:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c01013de:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c01013e2:	ee                   	out    %al,(%dx)
}
c01013e3:	90                   	nop
}
c01013e4:	90                   	nop
c01013e5:	89 ec                	mov    %ebp,%esp
c01013e7:	5d                   	pop    %ebp
c01013e8:	c3                   	ret    

c01013e9 <serial_putc>:

/* serial_putc - print character to serial port */
static void
serial_putc(int c) {
c01013e9:	55                   	push   %ebp
c01013ea:	89 e5                	mov    %esp,%ebp
c01013ec:	83 ec 04             	sub    $0x4,%esp
    if (c != '\b') {
c01013ef:	83 7d 08 08          	cmpl   $0x8,0x8(%ebp)
c01013f3:	74 0d                	je     c0101402 <serial_putc+0x19>
        serial_putc_sub(c);
c01013f5:	8b 45 08             	mov    0x8(%ebp),%eax
c01013f8:	89 04 24             	mov    %eax,(%esp)
c01013fb:	e8 8d ff ff ff       	call   c010138d <serial_putc_sub>
    else {
        serial_putc_sub('\b');
        serial_putc_sub(' ');
        serial_putc_sub('\b');
    }
}
c0101400:	eb 24                	jmp    c0101426 <serial_putc+0x3d>
        serial_putc_sub('\b');
c0101402:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c0101409:	e8 7f ff ff ff       	call   c010138d <serial_putc_sub>
        serial_putc_sub(' ');
c010140e:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c0101415:	e8 73 ff ff ff       	call   c010138d <serial_putc_sub>
        serial_putc_sub('\b');
c010141a:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c0101421:	e8 67 ff ff ff       	call   c010138d <serial_putc_sub>
}
c0101426:	90                   	nop
c0101427:	89 ec                	mov    %ebp,%esp
c0101429:	5d                   	pop    %ebp
c010142a:	c3                   	ret    

c010142b <cons_intr>:
/* *
 * cons_intr - called by device interrupt routines to feed input
 * characters into the circular console input buffer.
 * */
static void
cons_intr(int (*proc)(void)) {
c010142b:	55                   	push   %ebp
c010142c:	89 e5                	mov    %esp,%ebp
c010142e:	83 ec 18             	sub    $0x18,%esp
    int c;
    while ((c = (*proc)()) != -1) {
c0101431:	eb 33                	jmp    c0101466 <cons_intr+0x3b>
        if (c != 0) {
c0101433:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0101437:	74 2d                	je     c0101466 <cons_intr+0x3b>
            cons.buf[cons.wpos ++] = c;
c0101439:	a1 64 36 1a c0       	mov    0xc01a3664,%eax
c010143e:	8d 50 01             	lea    0x1(%eax),%edx
c0101441:	89 15 64 36 1a c0    	mov    %edx,0xc01a3664
c0101447:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010144a:	88 90 60 34 1a c0    	mov    %dl,-0x3fe5cba0(%eax)
            if (cons.wpos == CONSBUFSIZE) {
c0101450:	a1 64 36 1a c0       	mov    0xc01a3664,%eax
c0101455:	3d 00 02 00 00       	cmp    $0x200,%eax
c010145a:	75 0a                	jne    c0101466 <cons_intr+0x3b>
                cons.wpos = 0;
c010145c:	c7 05 64 36 1a c0 00 	movl   $0x0,0xc01a3664
c0101463:	00 00 00 
    while ((c = (*proc)()) != -1) {
c0101466:	8b 45 08             	mov    0x8(%ebp),%eax
c0101469:	ff d0                	call   *%eax
c010146b:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010146e:	83 7d f4 ff          	cmpl   $0xffffffff,-0xc(%ebp)
c0101472:	75 bf                	jne    c0101433 <cons_intr+0x8>
            }
        }
    }
}
c0101474:	90                   	nop
c0101475:	90                   	nop
c0101476:	89 ec                	mov    %ebp,%esp
c0101478:	5d                   	pop    %ebp
c0101479:	c3                   	ret    

c010147a <serial_proc_data>:

/* serial_proc_data - get data from serial port */
static int
serial_proc_data(void) {
c010147a:	55                   	push   %ebp
c010147b:	89 e5                	mov    %esp,%ebp
c010147d:	83 ec 10             	sub    $0x10,%esp
c0101480:	66 c7 45 fa fd 03    	movw   $0x3fd,-0x6(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101486:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c010148a:	89 c2                	mov    %eax,%edx
c010148c:	ec                   	in     (%dx),%al
c010148d:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c0101490:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
    if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) {
c0101494:	0f b6 c0             	movzbl %al,%eax
c0101497:	83 e0 01             	and    $0x1,%eax
c010149a:	85 c0                	test   %eax,%eax
c010149c:	75 07                	jne    c01014a5 <serial_proc_data+0x2b>
        return -1;
c010149e:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c01014a3:	eb 2a                	jmp    c01014cf <serial_proc_data+0x55>
c01014a5:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01014ab:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c01014af:	89 c2                	mov    %eax,%edx
c01014b1:	ec                   	in     (%dx),%al
c01014b2:	88 45 f5             	mov    %al,-0xb(%ebp)
    return data;
c01014b5:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
    }
    int c = inb(COM1 + COM_RX);
c01014b9:	0f b6 c0             	movzbl %al,%eax
c01014bc:	89 45 fc             	mov    %eax,-0x4(%ebp)
    if (c == 127) {
c01014bf:	83 7d fc 7f          	cmpl   $0x7f,-0x4(%ebp)
c01014c3:	75 07                	jne    c01014cc <serial_proc_data+0x52>
        c = '\b';
c01014c5:	c7 45 fc 08 00 00 00 	movl   $0x8,-0x4(%ebp)
    }
    return c;
c01014cc:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c01014cf:	89 ec                	mov    %ebp,%esp
c01014d1:	5d                   	pop    %ebp
c01014d2:	c3                   	ret    

c01014d3 <serial_intr>:

/* serial_intr - try to feed input characters from serial port */
void
serial_intr(void) {
c01014d3:	55                   	push   %ebp
c01014d4:	89 e5                	mov    %esp,%ebp
c01014d6:	83 ec 18             	sub    $0x18,%esp
    if (serial_exists) {
c01014d9:	a1 48 34 1a c0       	mov    0xc01a3448,%eax
c01014de:	85 c0                	test   %eax,%eax
c01014e0:	74 0c                	je     c01014ee <serial_intr+0x1b>
        cons_intr(serial_proc_data);
c01014e2:	c7 04 24 7a 14 10 c0 	movl   $0xc010147a,(%esp)
c01014e9:	e8 3d ff ff ff       	call   c010142b <cons_intr>
    }
}
c01014ee:	90                   	nop
c01014ef:	89 ec                	mov    %ebp,%esp
c01014f1:	5d                   	pop    %ebp
c01014f2:	c3                   	ret    

c01014f3 <kbd_proc_data>:
 *
 * The kbd_proc_data() function gets data from the keyboard.
 * If we finish a character, return it, else 0. And return -1 if no data.
 * */
static int
kbd_proc_data(void) {
c01014f3:	55                   	push   %ebp
c01014f4:	89 e5                	mov    %esp,%ebp
c01014f6:	83 ec 38             	sub    $0x38,%esp
c01014f9:	66 c7 45 f0 64 00    	movw   $0x64,-0x10(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01014ff:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101502:	89 c2                	mov    %eax,%edx
c0101504:	ec                   	in     (%dx),%al
c0101505:	88 45 ef             	mov    %al,-0x11(%ebp)
    return data;
c0101508:	0f b6 45 ef          	movzbl -0x11(%ebp),%eax
    int c;
    uint8_t data;
    static uint32_t shift;

    if ((inb(KBSTATP) & KBS_DIB) == 0) {
c010150c:	0f b6 c0             	movzbl %al,%eax
c010150f:	83 e0 01             	and    $0x1,%eax
c0101512:	85 c0                	test   %eax,%eax
c0101514:	75 0a                	jne    c0101520 <kbd_proc_data+0x2d>
        return -1;
c0101516:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c010151b:	e9 56 01 00 00       	jmp    c0101676 <kbd_proc_data+0x183>
c0101520:	66 c7 45 ec 60 00    	movw   $0x60,-0x14(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101526:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101529:	89 c2                	mov    %eax,%edx
c010152b:	ec                   	in     (%dx),%al
c010152c:	88 45 eb             	mov    %al,-0x15(%ebp)
    return data;
c010152f:	0f b6 45 eb          	movzbl -0x15(%ebp),%eax
    }

    data = inb(KBDATAP);
c0101533:	88 45 f3             	mov    %al,-0xd(%ebp)

    if (data == 0xE0) {
c0101536:	80 7d f3 e0          	cmpb   $0xe0,-0xd(%ebp)
c010153a:	75 17                	jne    c0101553 <kbd_proc_data+0x60>
        // E0 escape character
        shift |= E0ESC;
c010153c:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c0101541:	83 c8 40             	or     $0x40,%eax
c0101544:	a3 68 36 1a c0       	mov    %eax,0xc01a3668
        return 0;
c0101549:	b8 00 00 00 00       	mov    $0x0,%eax
c010154e:	e9 23 01 00 00       	jmp    c0101676 <kbd_proc_data+0x183>
    } else if (data & 0x80) {
c0101553:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101557:	84 c0                	test   %al,%al
c0101559:	79 45                	jns    c01015a0 <kbd_proc_data+0xad>
        // Key released
        data = (shift & E0ESC ? data : data & 0x7F);
c010155b:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c0101560:	83 e0 40             	and    $0x40,%eax
c0101563:	85 c0                	test   %eax,%eax
c0101565:	75 08                	jne    c010156f <kbd_proc_data+0x7c>
c0101567:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c010156b:	24 7f                	and    $0x7f,%al
c010156d:	eb 04                	jmp    c0101573 <kbd_proc_data+0x80>
c010156f:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101573:	88 45 f3             	mov    %al,-0xd(%ebp)
        shift &= ~(shiftcode[data] | E0ESC);
c0101576:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c010157a:	0f b6 80 40 f0 12 c0 	movzbl -0x3fed0fc0(%eax),%eax
c0101581:	0c 40                	or     $0x40,%al
c0101583:	0f b6 c0             	movzbl %al,%eax
c0101586:	f7 d0                	not    %eax
c0101588:	89 c2                	mov    %eax,%edx
c010158a:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c010158f:	21 d0                	and    %edx,%eax
c0101591:	a3 68 36 1a c0       	mov    %eax,0xc01a3668
        return 0;
c0101596:	b8 00 00 00 00       	mov    $0x0,%eax
c010159b:	e9 d6 00 00 00       	jmp    c0101676 <kbd_proc_data+0x183>
    } else if (shift & E0ESC) {
c01015a0:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c01015a5:	83 e0 40             	and    $0x40,%eax
c01015a8:	85 c0                	test   %eax,%eax
c01015aa:	74 11                	je     c01015bd <kbd_proc_data+0xca>
        // Last character was an E0 escape; or with 0x80
        data |= 0x80;
c01015ac:	80 4d f3 80          	orb    $0x80,-0xd(%ebp)
        shift &= ~E0ESC;
c01015b0:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c01015b5:	83 e0 bf             	and    $0xffffffbf,%eax
c01015b8:	a3 68 36 1a c0       	mov    %eax,0xc01a3668
    }

    shift |= shiftcode[data];
c01015bd:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c01015c1:	0f b6 80 40 f0 12 c0 	movzbl -0x3fed0fc0(%eax),%eax
c01015c8:	0f b6 d0             	movzbl %al,%edx
c01015cb:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c01015d0:	09 d0                	or     %edx,%eax
c01015d2:	a3 68 36 1a c0       	mov    %eax,0xc01a3668
    shift ^= togglecode[data];
c01015d7:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c01015db:	0f b6 80 40 f1 12 c0 	movzbl -0x3fed0ec0(%eax),%eax
c01015e2:	0f b6 d0             	movzbl %al,%edx
c01015e5:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c01015ea:	31 d0                	xor    %edx,%eax
c01015ec:	a3 68 36 1a c0       	mov    %eax,0xc01a3668

    c = charcode[shift & (CTL | SHIFT)][data];
c01015f1:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c01015f6:	83 e0 03             	and    $0x3,%eax
c01015f9:	8b 14 85 40 f5 12 c0 	mov    -0x3fed0ac0(,%eax,4),%edx
c0101600:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101604:	01 d0                	add    %edx,%eax
c0101606:	0f b6 00             	movzbl (%eax),%eax
c0101609:	0f b6 c0             	movzbl %al,%eax
c010160c:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (shift & CAPSLOCK) {
c010160f:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c0101614:	83 e0 08             	and    $0x8,%eax
c0101617:	85 c0                	test   %eax,%eax
c0101619:	74 22                	je     c010163d <kbd_proc_data+0x14a>
        if ('a' <= c && c <= 'z')
c010161b:	83 7d f4 60          	cmpl   $0x60,-0xc(%ebp)
c010161f:	7e 0c                	jle    c010162d <kbd_proc_data+0x13a>
c0101621:	83 7d f4 7a          	cmpl   $0x7a,-0xc(%ebp)
c0101625:	7f 06                	jg     c010162d <kbd_proc_data+0x13a>
            c += 'A' - 'a';
c0101627:	83 6d f4 20          	subl   $0x20,-0xc(%ebp)
c010162b:	eb 10                	jmp    c010163d <kbd_proc_data+0x14a>
        else if ('A' <= c && c <= 'Z')
c010162d:	83 7d f4 40          	cmpl   $0x40,-0xc(%ebp)
c0101631:	7e 0a                	jle    c010163d <kbd_proc_data+0x14a>
c0101633:	83 7d f4 5a          	cmpl   $0x5a,-0xc(%ebp)
c0101637:	7f 04                	jg     c010163d <kbd_proc_data+0x14a>
            c += 'a' - 'A';
c0101639:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
    }

    // Process special keys
    // Ctrl-Alt-Del: reboot
    if (!(~shift & (CTL | ALT)) && c == KEY_DEL) {
c010163d:	a1 68 36 1a c0       	mov    0xc01a3668,%eax
c0101642:	f7 d0                	not    %eax
c0101644:	83 e0 06             	and    $0x6,%eax
c0101647:	85 c0                	test   %eax,%eax
c0101649:	75 28                	jne    c0101673 <kbd_proc_data+0x180>
c010164b:	81 7d f4 e9 00 00 00 	cmpl   $0xe9,-0xc(%ebp)
c0101652:	75 1f                	jne    c0101673 <kbd_proc_data+0x180>
        cprintf("Rebooting!\n");
c0101654:	c7 04 24 87 c2 10 c0 	movl   $0xc010c287,(%esp)
c010165b:	e8 18 ed ff ff       	call   c0100378 <cprintf>
c0101660:	66 c7 45 e8 92 00    	movw   $0x92,-0x18(%ebp)
c0101666:	c6 45 e7 03          	movb   $0x3,-0x19(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010166a:	0f b6 45 e7          	movzbl -0x19(%ebp),%eax
c010166e:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0101671:	ee                   	out    %al,(%dx)
}
c0101672:	90                   	nop
        outb(0x92, 0x3); // courtesy of Chris Frost
    }
    return c;
c0101673:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101676:	89 ec                	mov    %ebp,%esp
c0101678:	5d                   	pop    %ebp
c0101679:	c3                   	ret    

c010167a <kbd_intr>:

/* kbd_intr - try to feed input characters from keyboard */
static void
kbd_intr(void) {
c010167a:	55                   	push   %ebp
c010167b:	89 e5                	mov    %esp,%ebp
c010167d:	83 ec 18             	sub    $0x18,%esp
    cons_intr(kbd_proc_data);
c0101680:	c7 04 24 f3 14 10 c0 	movl   $0xc01014f3,(%esp)
c0101687:	e8 9f fd ff ff       	call   c010142b <cons_intr>
}
c010168c:	90                   	nop
c010168d:	89 ec                	mov    %ebp,%esp
c010168f:	5d                   	pop    %ebp
c0101690:	c3                   	ret    

c0101691 <kbd_init>:

static void
kbd_init(void) {
c0101691:	55                   	push   %ebp
c0101692:	89 e5                	mov    %esp,%ebp
c0101694:	83 ec 18             	sub    $0x18,%esp
    // drain the kbd buffer
    kbd_intr();
c0101697:	e8 de ff ff ff       	call   c010167a <kbd_intr>
    pic_enable(IRQ_KBD);
c010169c:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01016a3:	e8 ae 09 00 00       	call   c0102056 <pic_enable>
}
c01016a8:	90                   	nop
c01016a9:	89 ec                	mov    %ebp,%esp
c01016ab:	5d                   	pop    %ebp
c01016ac:	c3                   	ret    

c01016ad <cons_init>:

/* cons_init - initializes the console devices */
void
cons_init(void) {
c01016ad:	55                   	push   %ebp
c01016ae:	89 e5                	mov    %esp,%ebp
c01016b0:	83 ec 18             	sub    $0x18,%esp
    cga_init();
c01016b3:	e8 4a f8 ff ff       	call   c0100f02 <cga_init>
    serial_init();
c01016b8:	e8 2d f9 ff ff       	call   c0100fea <serial_init>
    kbd_init();
c01016bd:	e8 cf ff ff ff       	call   c0101691 <kbd_init>
    if (!serial_exists) {
c01016c2:	a1 48 34 1a c0       	mov    0xc01a3448,%eax
c01016c7:	85 c0                	test   %eax,%eax
c01016c9:	75 0c                	jne    c01016d7 <cons_init+0x2a>
        cprintf("serial port does not exist!!\n");
c01016cb:	c7 04 24 93 c2 10 c0 	movl   $0xc010c293,(%esp)
c01016d2:	e8 a1 ec ff ff       	call   c0100378 <cprintf>
    }
}
c01016d7:	90                   	nop
c01016d8:	89 ec                	mov    %ebp,%esp
c01016da:	5d                   	pop    %ebp
c01016db:	c3                   	ret    

c01016dc <cons_putc>:

/* cons_putc - print a single character @c to console devices */
void
cons_putc(int c) {
c01016dc:	55                   	push   %ebp
c01016dd:	89 e5                	mov    %esp,%ebp
c01016df:	83 ec 28             	sub    $0x28,%esp
    bool intr_flag;
    local_intr_save(intr_flag);
c01016e2:	e8 8e f7 ff ff       	call   c0100e75 <__intr_save>
c01016e7:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        lpt_putc(c);
c01016ea:	8b 45 08             	mov    0x8(%ebp),%eax
c01016ed:	89 04 24             	mov    %eax,(%esp)
c01016f0:	e8 60 fa ff ff       	call   c0101155 <lpt_putc>
        cga_putc(c);
c01016f5:	8b 45 08             	mov    0x8(%ebp),%eax
c01016f8:	89 04 24             	mov    %eax,(%esp)
c01016fb:	e8 97 fa ff ff       	call   c0101197 <cga_putc>
        serial_putc(c);
c0101700:	8b 45 08             	mov    0x8(%ebp),%eax
c0101703:	89 04 24             	mov    %eax,(%esp)
c0101706:	e8 de fc ff ff       	call   c01013e9 <serial_putc>
    }
    local_intr_restore(intr_flag);
c010170b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010170e:	89 04 24             	mov    %eax,(%esp)
c0101711:	e8 8b f7 ff ff       	call   c0100ea1 <__intr_restore>
}
c0101716:	90                   	nop
c0101717:	89 ec                	mov    %ebp,%esp
c0101719:	5d                   	pop    %ebp
c010171a:	c3                   	ret    

c010171b <cons_getc>:
/* *
 * cons_getc - return the next input character from console,
 * or 0 if none waiting.
 * */
int
cons_getc(void) {
c010171b:	55                   	push   %ebp
c010171c:	89 e5                	mov    %esp,%ebp
c010171e:	83 ec 28             	sub    $0x28,%esp
    int c = 0;
c0101721:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    bool intr_flag;
    local_intr_save(intr_flag);
c0101728:	e8 48 f7 ff ff       	call   c0100e75 <__intr_save>
c010172d:	89 45 f0             	mov    %eax,-0x10(%ebp)
    {
        // poll for any pending input characters,
        // so that this function works even when interrupts are disabled
        // (e.g., when called from the kernel monitor).
        serial_intr();
c0101730:	e8 9e fd ff ff       	call   c01014d3 <serial_intr>
        kbd_intr();
c0101735:	e8 40 ff ff ff       	call   c010167a <kbd_intr>

        // grab the next character from the input buffer.
        if (cons.rpos != cons.wpos) {
c010173a:	8b 15 60 36 1a c0    	mov    0xc01a3660,%edx
c0101740:	a1 64 36 1a c0       	mov    0xc01a3664,%eax
c0101745:	39 c2                	cmp    %eax,%edx
c0101747:	74 31                	je     c010177a <cons_getc+0x5f>
            c = cons.buf[cons.rpos ++];
c0101749:	a1 60 36 1a c0       	mov    0xc01a3660,%eax
c010174e:	8d 50 01             	lea    0x1(%eax),%edx
c0101751:	89 15 60 36 1a c0    	mov    %edx,0xc01a3660
c0101757:	0f b6 80 60 34 1a c0 	movzbl -0x3fe5cba0(%eax),%eax
c010175e:	0f b6 c0             	movzbl %al,%eax
c0101761:	89 45 f4             	mov    %eax,-0xc(%ebp)
            if (cons.rpos == CONSBUFSIZE) {
c0101764:	a1 60 36 1a c0       	mov    0xc01a3660,%eax
c0101769:	3d 00 02 00 00       	cmp    $0x200,%eax
c010176e:	75 0a                	jne    c010177a <cons_getc+0x5f>
                cons.rpos = 0;
c0101770:	c7 05 60 36 1a c0 00 	movl   $0x0,0xc01a3660
c0101777:	00 00 00 
            }
        }
    }
    local_intr_restore(intr_flag);
c010177a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010177d:	89 04 24             	mov    %eax,(%esp)
c0101780:	e8 1c f7 ff ff       	call   c0100ea1 <__intr_restore>
    return c;
c0101785:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101788:	89 ec                	mov    %ebp,%esp
c010178a:	5d                   	pop    %ebp
c010178b:	c3                   	ret    

c010178c <ide_wait_ready>:
    unsigned int size;          // Size in Sectors
    unsigned char model[41];    // Model in String
} ide_devices[MAX_IDE];

static int
ide_wait_ready(unsigned short iobase, bool check_error) {
c010178c:	55                   	push   %ebp
c010178d:	89 e5                	mov    %esp,%ebp
c010178f:	83 ec 14             	sub    $0x14,%esp
c0101792:	8b 45 08             	mov    0x8(%ebp),%eax
c0101795:	66 89 45 ec          	mov    %ax,-0x14(%ebp)
    int r;
    while ((r = inb(iobase + ISA_STATUS)) & IDE_BSY)
c0101799:	90                   	nop
c010179a:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010179d:	83 c0 07             	add    $0x7,%eax
c01017a0:	0f b7 c0             	movzwl %ax,%eax
c01017a3:	66 89 45 fa          	mov    %ax,-0x6(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01017a7:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c01017ab:	89 c2                	mov    %eax,%edx
c01017ad:	ec                   	in     (%dx),%al
c01017ae:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c01017b1:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c01017b5:	0f b6 c0             	movzbl %al,%eax
c01017b8:	89 45 fc             	mov    %eax,-0x4(%ebp)
c01017bb:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01017be:	25 80 00 00 00       	and    $0x80,%eax
c01017c3:	85 c0                	test   %eax,%eax
c01017c5:	75 d3                	jne    c010179a <ide_wait_ready+0xe>
        /* nothing */;
    if (check_error && (r & (IDE_DF | IDE_ERR)) != 0) {
c01017c7:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c01017cb:	74 11                	je     c01017de <ide_wait_ready+0x52>
c01017cd:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01017d0:	83 e0 21             	and    $0x21,%eax
c01017d3:	85 c0                	test   %eax,%eax
c01017d5:	74 07                	je     c01017de <ide_wait_ready+0x52>
        return -1;
c01017d7:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c01017dc:	eb 05                	jmp    c01017e3 <ide_wait_ready+0x57>
    }
    return 0;
c01017de:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01017e3:	89 ec                	mov    %ebp,%esp
c01017e5:	5d                   	pop    %ebp
c01017e6:	c3                   	ret    

c01017e7 <ide_init>:

void
ide_init(void) {
c01017e7:	55                   	push   %ebp
c01017e8:	89 e5                	mov    %esp,%ebp
c01017ea:	57                   	push   %edi
c01017eb:	53                   	push   %ebx
c01017ec:	81 ec 50 02 00 00    	sub    $0x250,%esp
    static_assert((SECTSIZE % 4) == 0);
    unsigned short ideno, iobase;
    for (ideno = 0; ideno < MAX_IDE; ideno ++) {
c01017f2:	66 c7 45 f6 00 00    	movw   $0x0,-0xa(%ebp)
c01017f8:	e9 bd 02 00 00       	jmp    c0101aba <ide_init+0x2d3>
        /* assume that no device here */
        ide_devices[ideno].valid = 0;
c01017fd:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101801:	89 d0                	mov    %edx,%eax
c0101803:	c1 e0 03             	shl    $0x3,%eax
c0101806:	29 d0                	sub    %edx,%eax
c0101808:	c1 e0 03             	shl    $0x3,%eax
c010180b:	05 80 36 1a c0       	add    $0xc01a3680,%eax
c0101810:	c6 00 00             	movb   $0x0,(%eax)

        iobase = IO_BASE(ideno);
c0101813:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101817:	d1 e8                	shr    %eax
c0101819:	0f b7 c0             	movzwl %ax,%eax
c010181c:	8b 04 85 b4 c2 10 c0 	mov    -0x3fef3d4c(,%eax,4),%eax
c0101823:	66 89 45 ea          	mov    %ax,-0x16(%ebp)

        /* wait device ready */
        ide_wait_ready(iobase, 0);
c0101827:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c010182b:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0101832:	00 
c0101833:	89 04 24             	mov    %eax,(%esp)
c0101836:	e8 51 ff ff ff       	call   c010178c <ide_wait_ready>

        /* step1: select drive */
        outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4));
c010183b:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010183f:	c1 e0 04             	shl    $0x4,%eax
c0101842:	24 10                	and    $0x10,%al
c0101844:	0c e0                	or     $0xe0,%al
c0101846:	0f b6 c0             	movzbl %al,%eax
c0101849:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c010184d:	83 c2 06             	add    $0x6,%edx
c0101850:	0f b7 d2             	movzwl %dx,%edx
c0101853:	66 89 55 ca          	mov    %dx,-0x36(%ebp)
c0101857:	88 45 c9             	mov    %al,-0x37(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010185a:	0f b6 45 c9          	movzbl -0x37(%ebp),%eax
c010185e:	0f b7 55 ca          	movzwl -0x36(%ebp),%edx
c0101862:	ee                   	out    %al,(%dx)
}
c0101863:	90                   	nop
        ide_wait_ready(iobase, 0);
c0101864:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0101868:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010186f:	00 
c0101870:	89 04 24             	mov    %eax,(%esp)
c0101873:	e8 14 ff ff ff       	call   c010178c <ide_wait_ready>

        /* step2: send ATA identify command */
        outb(iobase + ISA_COMMAND, IDE_CMD_IDENTIFY);
c0101878:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c010187c:	83 c0 07             	add    $0x7,%eax
c010187f:	0f b7 c0             	movzwl %ax,%eax
c0101882:	66 89 45 ce          	mov    %ax,-0x32(%ebp)
c0101886:	c6 45 cd ec          	movb   $0xec,-0x33(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010188a:	0f b6 45 cd          	movzbl -0x33(%ebp),%eax
c010188e:	0f b7 55 ce          	movzwl -0x32(%ebp),%edx
c0101892:	ee                   	out    %al,(%dx)
}
c0101893:	90                   	nop
        ide_wait_ready(iobase, 0);
c0101894:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0101898:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010189f:	00 
c01018a0:	89 04 24             	mov    %eax,(%esp)
c01018a3:	e8 e4 fe ff ff       	call   c010178c <ide_wait_ready>

        /* step3: polling */
        if (inb(iobase + ISA_STATUS) == 0 || ide_wait_ready(iobase, 1) != 0) {
c01018a8:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c01018ac:	83 c0 07             	add    $0x7,%eax
c01018af:	0f b7 c0             	movzwl %ax,%eax
c01018b2:	66 89 45 d2          	mov    %ax,-0x2e(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01018b6:	0f b7 45 d2          	movzwl -0x2e(%ebp),%eax
c01018ba:	89 c2                	mov    %eax,%edx
c01018bc:	ec                   	in     (%dx),%al
c01018bd:	88 45 d1             	mov    %al,-0x2f(%ebp)
    return data;
c01018c0:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c01018c4:	84 c0                	test   %al,%al
c01018c6:	0f 84 e4 01 00 00    	je     c0101ab0 <ide_init+0x2c9>
c01018cc:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c01018d0:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01018d7:	00 
c01018d8:	89 04 24             	mov    %eax,(%esp)
c01018db:	e8 ac fe ff ff       	call   c010178c <ide_wait_ready>
c01018e0:	85 c0                	test   %eax,%eax
c01018e2:	0f 85 c8 01 00 00    	jne    c0101ab0 <ide_init+0x2c9>
            continue ;
        }

        /* device is ok */
        ide_devices[ideno].valid = 1;
c01018e8:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c01018ec:	89 d0                	mov    %edx,%eax
c01018ee:	c1 e0 03             	shl    $0x3,%eax
c01018f1:	29 d0                	sub    %edx,%eax
c01018f3:	c1 e0 03             	shl    $0x3,%eax
c01018f6:	05 80 36 1a c0       	add    $0xc01a3680,%eax
c01018fb:	c6 00 01             	movb   $0x1,(%eax)

        /* read identification space of the device */
        unsigned int buffer[128];
        insl(iobase + ISA_DATA, buffer, sizeof(buffer) / sizeof(unsigned int));
c01018fe:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0101902:	89 45 c4             	mov    %eax,-0x3c(%ebp)
c0101905:	8d 85 bc fd ff ff    	lea    -0x244(%ebp),%eax
c010190b:	89 45 c0             	mov    %eax,-0x40(%ebp)
c010190e:	c7 45 bc 80 00 00 00 	movl   $0x80,-0x44(%ebp)
    asm volatile (
c0101915:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c0101918:	8b 4d c0             	mov    -0x40(%ebp),%ecx
c010191b:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010191e:	89 cb                	mov    %ecx,%ebx
c0101920:	89 df                	mov    %ebx,%edi
c0101922:	89 c1                	mov    %eax,%ecx
c0101924:	fc                   	cld    
c0101925:	f2 6d                	repnz insl (%dx),%es:(%edi)
c0101927:	89 c8                	mov    %ecx,%eax
c0101929:	89 fb                	mov    %edi,%ebx
c010192b:	89 5d c0             	mov    %ebx,-0x40(%ebp)
c010192e:	89 45 bc             	mov    %eax,-0x44(%ebp)
}
c0101931:	90                   	nop

        unsigned char *ident = (unsigned char *)buffer;
c0101932:	8d 85 bc fd ff ff    	lea    -0x244(%ebp),%eax
c0101938:	89 45 e4             	mov    %eax,-0x1c(%ebp)
        unsigned int sectors;
        unsigned int cmdsets = *(unsigned int *)(ident + IDE_IDENT_CMDSETS);
c010193b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010193e:	8b 80 a4 00 00 00    	mov    0xa4(%eax),%eax
c0101944:	89 45 e0             	mov    %eax,-0x20(%ebp)
        /* device use 48-bits or 28-bits addressing */
        if (cmdsets & (1 << 26)) {
c0101947:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010194a:	25 00 00 00 04       	and    $0x4000000,%eax
c010194f:	85 c0                	test   %eax,%eax
c0101951:	74 0e                	je     c0101961 <ide_init+0x17a>
            sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA_EXT);
c0101953:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0101956:	8b 80 c8 00 00 00    	mov    0xc8(%eax),%eax
c010195c:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010195f:	eb 09                	jmp    c010196a <ide_init+0x183>
        }
        else {
            sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA);
c0101961:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0101964:	8b 40 78             	mov    0x78(%eax),%eax
c0101967:	89 45 f0             	mov    %eax,-0x10(%ebp)
        }
        ide_devices[ideno].sets = cmdsets;
c010196a:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c010196e:	89 d0                	mov    %edx,%eax
c0101970:	c1 e0 03             	shl    $0x3,%eax
c0101973:	29 d0                	sub    %edx,%eax
c0101975:	c1 e0 03             	shl    $0x3,%eax
c0101978:	8d 90 84 36 1a c0    	lea    -0x3fe5c97c(%eax),%edx
c010197e:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0101981:	89 02                	mov    %eax,(%edx)
        ide_devices[ideno].size = sectors;
c0101983:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101987:	89 d0                	mov    %edx,%eax
c0101989:	c1 e0 03             	shl    $0x3,%eax
c010198c:	29 d0                	sub    %edx,%eax
c010198e:	c1 e0 03             	shl    $0x3,%eax
c0101991:	8d 90 88 36 1a c0    	lea    -0x3fe5c978(%eax),%edx
c0101997:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010199a:	89 02                	mov    %eax,(%edx)

        /* check if supports LBA */
        assert((*(unsigned short *)(ident + IDE_IDENT_CAPABILITIES) & 0x200) != 0);
c010199c:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010199f:	83 c0 62             	add    $0x62,%eax
c01019a2:	0f b7 00             	movzwl (%eax),%eax
c01019a5:	25 00 02 00 00       	and    $0x200,%eax
c01019aa:	85 c0                	test   %eax,%eax
c01019ac:	75 24                	jne    c01019d2 <ide_init+0x1eb>
c01019ae:	c7 44 24 0c bc c2 10 	movl   $0xc010c2bc,0xc(%esp)
c01019b5:	c0 
c01019b6:	c7 44 24 08 ff c2 10 	movl   $0xc010c2ff,0x8(%esp)
c01019bd:	c0 
c01019be:	c7 44 24 04 7d 00 00 	movl   $0x7d,0x4(%esp)
c01019c5:	00 
c01019c6:	c7 04 24 14 c3 10 c0 	movl   $0xc010c314,(%esp)
c01019cd:	e8 69 f3 ff ff       	call   c0100d3b <__panic>

        unsigned char *model = ide_devices[ideno].model, *data = ident + IDE_IDENT_MODEL;
c01019d2:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c01019d6:	89 d0                	mov    %edx,%eax
c01019d8:	c1 e0 03             	shl    $0x3,%eax
c01019db:	29 d0                	sub    %edx,%eax
c01019dd:	c1 e0 03             	shl    $0x3,%eax
c01019e0:	05 80 36 1a c0       	add    $0xc01a3680,%eax
c01019e5:	83 c0 0c             	add    $0xc,%eax
c01019e8:	89 45 dc             	mov    %eax,-0x24(%ebp)
c01019eb:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01019ee:	83 c0 36             	add    $0x36,%eax
c01019f1:	89 45 d8             	mov    %eax,-0x28(%ebp)
        unsigned int i, length = 40;
c01019f4:	c7 45 d4 28 00 00 00 	movl   $0x28,-0x2c(%ebp)
        for (i = 0; i < length; i += 2) {
c01019fb:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0101a02:	eb 34                	jmp    c0101a38 <ide_init+0x251>
            model[i] = data[i + 1], model[i + 1] = data[i];
c0101a04:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101a07:	8d 50 01             	lea    0x1(%eax),%edx
c0101a0a:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0101a0d:	01 c2                	add    %eax,%edx
c0101a0f:	8b 4d dc             	mov    -0x24(%ebp),%ecx
c0101a12:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101a15:	01 c8                	add    %ecx,%eax
c0101a17:	0f b6 12             	movzbl (%edx),%edx
c0101a1a:	88 10                	mov    %dl,(%eax)
c0101a1c:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0101a1f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101a22:	01 c2                	add    %eax,%edx
c0101a24:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101a27:	8d 48 01             	lea    0x1(%eax),%ecx
c0101a2a:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0101a2d:	01 c8                	add    %ecx,%eax
c0101a2f:	0f b6 12             	movzbl (%edx),%edx
c0101a32:	88 10                	mov    %dl,(%eax)
        for (i = 0; i < length; i += 2) {
c0101a34:	83 45 ec 02          	addl   $0x2,-0x14(%ebp)
c0101a38:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101a3b:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c0101a3e:	72 c4                	jb     c0101a04 <ide_init+0x21d>
        }
        do {
            model[i] = '\0';
c0101a40:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0101a43:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101a46:	01 d0                	add    %edx,%eax
c0101a48:	c6 00 00             	movb   $0x0,(%eax)
        } while (i -- > 0 && model[i] == ' ');
c0101a4b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101a4e:	8d 50 ff             	lea    -0x1(%eax),%edx
c0101a51:	89 55 ec             	mov    %edx,-0x14(%ebp)
c0101a54:	85 c0                	test   %eax,%eax
c0101a56:	74 0f                	je     c0101a67 <ide_init+0x280>
c0101a58:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0101a5b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101a5e:	01 d0                	add    %edx,%eax
c0101a60:	0f b6 00             	movzbl (%eax),%eax
c0101a63:	3c 20                	cmp    $0x20,%al
c0101a65:	74 d9                	je     c0101a40 <ide_init+0x259>

        cprintf("ide %d: %10u(sectors), '%s'.\n", ideno, ide_devices[ideno].size, ide_devices[ideno].model);
c0101a67:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101a6b:	89 d0                	mov    %edx,%eax
c0101a6d:	c1 e0 03             	shl    $0x3,%eax
c0101a70:	29 d0                	sub    %edx,%eax
c0101a72:	c1 e0 03             	shl    $0x3,%eax
c0101a75:	05 80 36 1a c0       	add    $0xc01a3680,%eax
c0101a7a:	8d 48 0c             	lea    0xc(%eax),%ecx
c0101a7d:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101a81:	89 d0                	mov    %edx,%eax
c0101a83:	c1 e0 03             	shl    $0x3,%eax
c0101a86:	29 d0                	sub    %edx,%eax
c0101a88:	c1 e0 03             	shl    $0x3,%eax
c0101a8b:	05 88 36 1a c0       	add    $0xc01a3688,%eax
c0101a90:	8b 10                	mov    (%eax),%edx
c0101a92:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101a96:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c0101a9a:	89 54 24 08          	mov    %edx,0x8(%esp)
c0101a9e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0101aa2:	c7 04 24 26 c3 10 c0 	movl   $0xc010c326,(%esp)
c0101aa9:	e8 ca e8 ff ff       	call   c0100378 <cprintf>
c0101aae:	eb 01                	jmp    c0101ab1 <ide_init+0x2ca>
            continue ;
c0101ab0:	90                   	nop
    for (ideno = 0; ideno < MAX_IDE; ideno ++) {
c0101ab1:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101ab5:	40                   	inc    %eax
c0101ab6:	66 89 45 f6          	mov    %ax,-0xa(%ebp)
c0101aba:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101abe:	83 f8 03             	cmp    $0x3,%eax
c0101ac1:	0f 86 36 fd ff ff    	jbe    c01017fd <ide_init+0x16>
    }

    // enable ide interrupt
    pic_enable(IRQ_IDE1);
c0101ac7:	c7 04 24 0e 00 00 00 	movl   $0xe,(%esp)
c0101ace:	e8 83 05 00 00       	call   c0102056 <pic_enable>
    pic_enable(IRQ_IDE2);
c0101ad3:	c7 04 24 0f 00 00 00 	movl   $0xf,(%esp)
c0101ada:	e8 77 05 00 00       	call   c0102056 <pic_enable>
}
c0101adf:	90                   	nop
c0101ae0:	81 c4 50 02 00 00    	add    $0x250,%esp
c0101ae6:	5b                   	pop    %ebx
c0101ae7:	5f                   	pop    %edi
c0101ae8:	5d                   	pop    %ebp
c0101ae9:	c3                   	ret    

c0101aea <ide_device_valid>:

bool
ide_device_valid(unsigned short ideno) {
c0101aea:	55                   	push   %ebp
c0101aeb:	89 e5                	mov    %esp,%ebp
c0101aed:	83 ec 04             	sub    $0x4,%esp
c0101af0:	8b 45 08             	mov    0x8(%ebp),%eax
c0101af3:	66 89 45 fc          	mov    %ax,-0x4(%ebp)
    return VALID_IDE(ideno);
c0101af7:	0f b7 45 fc          	movzwl -0x4(%ebp),%eax
c0101afb:	83 f8 03             	cmp    $0x3,%eax
c0101afe:	77 21                	ja     c0101b21 <ide_device_valid+0x37>
c0101b00:	0f b7 55 fc          	movzwl -0x4(%ebp),%edx
c0101b04:	89 d0                	mov    %edx,%eax
c0101b06:	c1 e0 03             	shl    $0x3,%eax
c0101b09:	29 d0                	sub    %edx,%eax
c0101b0b:	c1 e0 03             	shl    $0x3,%eax
c0101b0e:	05 80 36 1a c0       	add    $0xc01a3680,%eax
c0101b13:	0f b6 00             	movzbl (%eax),%eax
c0101b16:	84 c0                	test   %al,%al
c0101b18:	74 07                	je     c0101b21 <ide_device_valid+0x37>
c0101b1a:	b8 01 00 00 00       	mov    $0x1,%eax
c0101b1f:	eb 05                	jmp    c0101b26 <ide_device_valid+0x3c>
c0101b21:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0101b26:	89 ec                	mov    %ebp,%esp
c0101b28:	5d                   	pop    %ebp
c0101b29:	c3                   	ret    

c0101b2a <ide_device_size>:

size_t
ide_device_size(unsigned short ideno) {
c0101b2a:	55                   	push   %ebp
c0101b2b:	89 e5                	mov    %esp,%ebp
c0101b2d:	83 ec 08             	sub    $0x8,%esp
c0101b30:	8b 45 08             	mov    0x8(%ebp),%eax
c0101b33:	66 89 45 fc          	mov    %ax,-0x4(%ebp)
    if (ide_device_valid(ideno)) {
c0101b37:	0f b7 45 fc          	movzwl -0x4(%ebp),%eax
c0101b3b:	89 04 24             	mov    %eax,(%esp)
c0101b3e:	e8 a7 ff ff ff       	call   c0101aea <ide_device_valid>
c0101b43:	85 c0                	test   %eax,%eax
c0101b45:	74 17                	je     c0101b5e <ide_device_size+0x34>
        return ide_devices[ideno].size;
c0101b47:	0f b7 55 fc          	movzwl -0x4(%ebp),%edx
c0101b4b:	89 d0                	mov    %edx,%eax
c0101b4d:	c1 e0 03             	shl    $0x3,%eax
c0101b50:	29 d0                	sub    %edx,%eax
c0101b52:	c1 e0 03             	shl    $0x3,%eax
c0101b55:	05 88 36 1a c0       	add    $0xc01a3688,%eax
c0101b5a:	8b 00                	mov    (%eax),%eax
c0101b5c:	eb 05                	jmp    c0101b63 <ide_device_size+0x39>
    }
    return 0;
c0101b5e:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0101b63:	89 ec                	mov    %ebp,%esp
c0101b65:	5d                   	pop    %ebp
c0101b66:	c3                   	ret    

c0101b67 <ide_read_secs>:

int
ide_read_secs(unsigned short ideno, uint32_t secno, void *dst, size_t nsecs) {
c0101b67:	55                   	push   %ebp
c0101b68:	89 e5                	mov    %esp,%ebp
c0101b6a:	57                   	push   %edi
c0101b6b:	53                   	push   %ebx
c0101b6c:	83 ec 50             	sub    $0x50,%esp
c0101b6f:	8b 45 08             	mov    0x8(%ebp),%eax
c0101b72:	66 89 45 c4          	mov    %ax,-0x3c(%ebp)
    assert(nsecs <= MAX_NSECS && VALID_IDE(ideno));
c0101b76:	81 7d 14 80 00 00 00 	cmpl   $0x80,0x14(%ebp)
c0101b7d:	77 23                	ja     c0101ba2 <ide_read_secs+0x3b>
c0101b7f:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101b83:	83 f8 03             	cmp    $0x3,%eax
c0101b86:	77 1a                	ja     c0101ba2 <ide_read_secs+0x3b>
c0101b88:	0f b7 55 c4          	movzwl -0x3c(%ebp),%edx
c0101b8c:	89 d0                	mov    %edx,%eax
c0101b8e:	c1 e0 03             	shl    $0x3,%eax
c0101b91:	29 d0                	sub    %edx,%eax
c0101b93:	c1 e0 03             	shl    $0x3,%eax
c0101b96:	05 80 36 1a c0       	add    $0xc01a3680,%eax
c0101b9b:	0f b6 00             	movzbl (%eax),%eax
c0101b9e:	84 c0                	test   %al,%al
c0101ba0:	75 24                	jne    c0101bc6 <ide_read_secs+0x5f>
c0101ba2:	c7 44 24 0c 44 c3 10 	movl   $0xc010c344,0xc(%esp)
c0101ba9:	c0 
c0101baa:	c7 44 24 08 ff c2 10 	movl   $0xc010c2ff,0x8(%esp)
c0101bb1:	c0 
c0101bb2:	c7 44 24 04 9f 00 00 	movl   $0x9f,0x4(%esp)
c0101bb9:	00 
c0101bba:	c7 04 24 14 c3 10 c0 	movl   $0xc010c314,(%esp)
c0101bc1:	e8 75 f1 ff ff       	call   c0100d3b <__panic>
    assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS);
c0101bc6:	81 7d 0c ff ff ff 0f 	cmpl   $0xfffffff,0xc(%ebp)
c0101bcd:	77 0f                	ja     c0101bde <ide_read_secs+0x77>
c0101bcf:	8b 55 0c             	mov    0xc(%ebp),%edx
c0101bd2:	8b 45 14             	mov    0x14(%ebp),%eax
c0101bd5:	01 d0                	add    %edx,%eax
c0101bd7:	3d 00 00 00 10       	cmp    $0x10000000,%eax
c0101bdc:	76 24                	jbe    c0101c02 <ide_read_secs+0x9b>
c0101bde:	c7 44 24 0c 6c c3 10 	movl   $0xc010c36c,0xc(%esp)
c0101be5:	c0 
c0101be6:	c7 44 24 08 ff c2 10 	movl   $0xc010c2ff,0x8(%esp)
c0101bed:	c0 
c0101bee:	c7 44 24 04 a0 00 00 	movl   $0xa0,0x4(%esp)
c0101bf5:	00 
c0101bf6:	c7 04 24 14 c3 10 c0 	movl   $0xc010c314,(%esp)
c0101bfd:	e8 39 f1 ff ff       	call   c0100d3b <__panic>
    unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno);
c0101c02:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101c06:	d1 e8                	shr    %eax
c0101c08:	0f b7 c0             	movzwl %ax,%eax
c0101c0b:	8b 04 85 b4 c2 10 c0 	mov    -0x3fef3d4c(,%eax,4),%eax
c0101c12:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
c0101c16:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101c1a:	d1 e8                	shr    %eax
c0101c1c:	0f b7 c0             	movzwl %ax,%eax
c0101c1f:	0f b7 04 85 b6 c2 10 	movzwl -0x3fef3d4a(,%eax,4),%eax
c0101c26:	c0 
c0101c27:	66 89 45 f0          	mov    %ax,-0x10(%ebp)

    ide_wait_ready(iobase, 0);
c0101c2b:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101c2f:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0101c36:	00 
c0101c37:	89 04 24             	mov    %eax,(%esp)
c0101c3a:	e8 4d fb ff ff       	call   c010178c <ide_wait_ready>

    // generate interrupt
    outb(ioctrl + ISA_CTRL, 0);
c0101c3f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101c42:	83 c0 02             	add    $0x2,%eax
c0101c45:	0f b7 c0             	movzwl %ax,%eax
c0101c48:	66 89 45 d6          	mov    %ax,-0x2a(%ebp)
c0101c4c:	c6 45 d5 00          	movb   $0x0,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101c50:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0101c54:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0101c58:	ee                   	out    %al,(%dx)
}
c0101c59:	90                   	nop
    outb(iobase + ISA_SECCNT, nsecs);
c0101c5a:	8b 45 14             	mov    0x14(%ebp),%eax
c0101c5d:	0f b6 c0             	movzbl %al,%eax
c0101c60:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101c64:	83 c2 02             	add    $0x2,%edx
c0101c67:	0f b7 d2             	movzwl %dx,%edx
c0101c6a:	66 89 55 da          	mov    %dx,-0x26(%ebp)
c0101c6e:	88 45 d9             	mov    %al,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101c71:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0101c75:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c0101c79:	ee                   	out    %al,(%dx)
}
c0101c7a:	90                   	nop
    outb(iobase + ISA_SECTOR, secno & 0xFF);
c0101c7b:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101c7e:	0f b6 c0             	movzbl %al,%eax
c0101c81:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101c85:	83 c2 03             	add    $0x3,%edx
c0101c88:	0f b7 d2             	movzwl %dx,%edx
c0101c8b:	66 89 55 de          	mov    %dx,-0x22(%ebp)
c0101c8f:	88 45 dd             	mov    %al,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101c92:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c0101c96:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0101c9a:	ee                   	out    %al,(%dx)
}
c0101c9b:	90                   	nop
    outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF);
c0101c9c:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101c9f:	c1 e8 08             	shr    $0x8,%eax
c0101ca2:	0f b6 c0             	movzbl %al,%eax
c0101ca5:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101ca9:	83 c2 04             	add    $0x4,%edx
c0101cac:	0f b7 d2             	movzwl %dx,%edx
c0101caf:	66 89 55 e2          	mov    %dx,-0x1e(%ebp)
c0101cb3:	88 45 e1             	mov    %al,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101cb6:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0101cba:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c0101cbe:	ee                   	out    %al,(%dx)
}
c0101cbf:	90                   	nop
    outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF);
c0101cc0:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101cc3:	c1 e8 10             	shr    $0x10,%eax
c0101cc6:	0f b6 c0             	movzbl %al,%eax
c0101cc9:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101ccd:	83 c2 05             	add    $0x5,%edx
c0101cd0:	0f b7 d2             	movzwl %dx,%edx
c0101cd3:	66 89 55 e6          	mov    %dx,-0x1a(%ebp)
c0101cd7:	88 45 e5             	mov    %al,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101cda:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101cde:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101ce2:	ee                   	out    %al,(%dx)
}
c0101ce3:	90                   	nop
    outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF));
c0101ce4:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0101ce7:	c0 e0 04             	shl    $0x4,%al
c0101cea:	24 10                	and    $0x10,%al
c0101cec:	88 c2                	mov    %al,%dl
c0101cee:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101cf1:	c1 e8 18             	shr    $0x18,%eax
c0101cf4:	24 0f                	and    $0xf,%al
c0101cf6:	08 d0                	or     %dl,%al
c0101cf8:	0c e0                	or     $0xe0,%al
c0101cfa:	0f b6 c0             	movzbl %al,%eax
c0101cfd:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101d01:	83 c2 06             	add    $0x6,%edx
c0101d04:	0f b7 d2             	movzwl %dx,%edx
c0101d07:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c0101d0b:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101d0e:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0101d12:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0101d16:	ee                   	out    %al,(%dx)
}
c0101d17:	90                   	nop
    outb(iobase + ISA_COMMAND, IDE_CMD_READ);
c0101d18:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101d1c:	83 c0 07             	add    $0x7,%eax
c0101d1f:	0f b7 c0             	movzwl %ax,%eax
c0101d22:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101d26:	c6 45 ed 20          	movb   $0x20,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101d2a:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101d2e:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101d32:	ee                   	out    %al,(%dx)
}
c0101d33:	90                   	nop

    int ret = 0;
c0101d34:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    for (; nsecs > 0; nsecs --, dst += SECTSIZE) {
c0101d3b:	eb 58                	jmp    c0101d95 <ide_read_secs+0x22e>
        if ((ret = ide_wait_ready(iobase, 1)) != 0) {
c0101d3d:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101d41:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0101d48:	00 
c0101d49:	89 04 24             	mov    %eax,(%esp)
c0101d4c:	e8 3b fa ff ff       	call   c010178c <ide_wait_ready>
c0101d51:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0101d54:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0101d58:	75 43                	jne    c0101d9d <ide_read_secs+0x236>
            goto out;
        }
        insl(iobase, dst, SECTSIZE / sizeof(uint32_t));
c0101d5a:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101d5e:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0101d61:	8b 45 10             	mov    0x10(%ebp),%eax
c0101d64:	89 45 cc             	mov    %eax,-0x34(%ebp)
c0101d67:	c7 45 c8 80 00 00 00 	movl   $0x80,-0x38(%ebp)
    asm volatile (
c0101d6e:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0101d71:	8b 4d cc             	mov    -0x34(%ebp),%ecx
c0101d74:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0101d77:	89 cb                	mov    %ecx,%ebx
c0101d79:	89 df                	mov    %ebx,%edi
c0101d7b:	89 c1                	mov    %eax,%ecx
c0101d7d:	fc                   	cld    
c0101d7e:	f2 6d                	repnz insl (%dx),%es:(%edi)
c0101d80:	89 c8                	mov    %ecx,%eax
c0101d82:	89 fb                	mov    %edi,%ebx
c0101d84:	89 5d cc             	mov    %ebx,-0x34(%ebp)
c0101d87:	89 45 c8             	mov    %eax,-0x38(%ebp)
}
c0101d8a:	90                   	nop
    for (; nsecs > 0; nsecs --, dst += SECTSIZE) {
c0101d8b:	ff 4d 14             	decl   0x14(%ebp)
c0101d8e:	81 45 10 00 02 00 00 	addl   $0x200,0x10(%ebp)
c0101d95:	83 7d 14 00          	cmpl   $0x0,0x14(%ebp)
c0101d99:	75 a2                	jne    c0101d3d <ide_read_secs+0x1d6>
    }

out:
c0101d9b:	eb 01                	jmp    c0101d9e <ide_read_secs+0x237>
            goto out;
c0101d9d:	90                   	nop
    return ret;
c0101d9e:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101da1:	83 c4 50             	add    $0x50,%esp
c0101da4:	5b                   	pop    %ebx
c0101da5:	5f                   	pop    %edi
c0101da6:	5d                   	pop    %ebp
c0101da7:	c3                   	ret    

c0101da8 <ide_write_secs>:

int
ide_write_secs(unsigned short ideno, uint32_t secno, const void *src, size_t nsecs) {
c0101da8:	55                   	push   %ebp
c0101da9:	89 e5                	mov    %esp,%ebp
c0101dab:	56                   	push   %esi
c0101dac:	53                   	push   %ebx
c0101dad:	83 ec 50             	sub    $0x50,%esp
c0101db0:	8b 45 08             	mov    0x8(%ebp),%eax
c0101db3:	66 89 45 c4          	mov    %ax,-0x3c(%ebp)
    assert(nsecs <= MAX_NSECS && VALID_IDE(ideno));
c0101db7:	81 7d 14 80 00 00 00 	cmpl   $0x80,0x14(%ebp)
c0101dbe:	77 23                	ja     c0101de3 <ide_write_secs+0x3b>
c0101dc0:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101dc4:	83 f8 03             	cmp    $0x3,%eax
c0101dc7:	77 1a                	ja     c0101de3 <ide_write_secs+0x3b>
c0101dc9:	0f b7 55 c4          	movzwl -0x3c(%ebp),%edx
c0101dcd:	89 d0                	mov    %edx,%eax
c0101dcf:	c1 e0 03             	shl    $0x3,%eax
c0101dd2:	29 d0                	sub    %edx,%eax
c0101dd4:	c1 e0 03             	shl    $0x3,%eax
c0101dd7:	05 80 36 1a c0       	add    $0xc01a3680,%eax
c0101ddc:	0f b6 00             	movzbl (%eax),%eax
c0101ddf:	84 c0                	test   %al,%al
c0101de1:	75 24                	jne    c0101e07 <ide_write_secs+0x5f>
c0101de3:	c7 44 24 0c 44 c3 10 	movl   $0xc010c344,0xc(%esp)
c0101dea:	c0 
c0101deb:	c7 44 24 08 ff c2 10 	movl   $0xc010c2ff,0x8(%esp)
c0101df2:	c0 
c0101df3:	c7 44 24 04 bc 00 00 	movl   $0xbc,0x4(%esp)
c0101dfa:	00 
c0101dfb:	c7 04 24 14 c3 10 c0 	movl   $0xc010c314,(%esp)
c0101e02:	e8 34 ef ff ff       	call   c0100d3b <__panic>
    assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS);
c0101e07:	81 7d 0c ff ff ff 0f 	cmpl   $0xfffffff,0xc(%ebp)
c0101e0e:	77 0f                	ja     c0101e1f <ide_write_secs+0x77>
c0101e10:	8b 55 0c             	mov    0xc(%ebp),%edx
c0101e13:	8b 45 14             	mov    0x14(%ebp),%eax
c0101e16:	01 d0                	add    %edx,%eax
c0101e18:	3d 00 00 00 10       	cmp    $0x10000000,%eax
c0101e1d:	76 24                	jbe    c0101e43 <ide_write_secs+0x9b>
c0101e1f:	c7 44 24 0c 6c c3 10 	movl   $0xc010c36c,0xc(%esp)
c0101e26:	c0 
c0101e27:	c7 44 24 08 ff c2 10 	movl   $0xc010c2ff,0x8(%esp)
c0101e2e:	c0 
c0101e2f:	c7 44 24 04 bd 00 00 	movl   $0xbd,0x4(%esp)
c0101e36:	00 
c0101e37:	c7 04 24 14 c3 10 c0 	movl   $0xc010c314,(%esp)
c0101e3e:	e8 f8 ee ff ff       	call   c0100d3b <__panic>
    unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno);
c0101e43:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101e47:	d1 e8                	shr    %eax
c0101e49:	0f b7 c0             	movzwl %ax,%eax
c0101e4c:	8b 04 85 b4 c2 10 c0 	mov    -0x3fef3d4c(,%eax,4),%eax
c0101e53:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
c0101e57:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101e5b:	d1 e8                	shr    %eax
c0101e5d:	0f b7 c0             	movzwl %ax,%eax
c0101e60:	0f b7 04 85 b6 c2 10 	movzwl -0x3fef3d4a(,%eax,4),%eax
c0101e67:	c0 
c0101e68:	66 89 45 f0          	mov    %ax,-0x10(%ebp)

    ide_wait_ready(iobase, 0);
c0101e6c:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101e70:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0101e77:	00 
c0101e78:	89 04 24             	mov    %eax,(%esp)
c0101e7b:	e8 0c f9 ff ff       	call   c010178c <ide_wait_ready>

    // generate interrupt
    outb(ioctrl + ISA_CTRL, 0);
c0101e80:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101e83:	83 c0 02             	add    $0x2,%eax
c0101e86:	0f b7 c0             	movzwl %ax,%eax
c0101e89:	66 89 45 d6          	mov    %ax,-0x2a(%ebp)
c0101e8d:	c6 45 d5 00          	movb   $0x0,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101e91:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0101e95:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0101e99:	ee                   	out    %al,(%dx)
}
c0101e9a:	90                   	nop
    outb(iobase + ISA_SECCNT, nsecs);
c0101e9b:	8b 45 14             	mov    0x14(%ebp),%eax
c0101e9e:	0f b6 c0             	movzbl %al,%eax
c0101ea1:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101ea5:	83 c2 02             	add    $0x2,%edx
c0101ea8:	0f b7 d2             	movzwl %dx,%edx
c0101eab:	66 89 55 da          	mov    %dx,-0x26(%ebp)
c0101eaf:	88 45 d9             	mov    %al,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101eb2:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0101eb6:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c0101eba:	ee                   	out    %al,(%dx)
}
c0101ebb:	90                   	nop
    outb(iobase + ISA_SECTOR, secno & 0xFF);
c0101ebc:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101ebf:	0f b6 c0             	movzbl %al,%eax
c0101ec2:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101ec6:	83 c2 03             	add    $0x3,%edx
c0101ec9:	0f b7 d2             	movzwl %dx,%edx
c0101ecc:	66 89 55 de          	mov    %dx,-0x22(%ebp)
c0101ed0:	88 45 dd             	mov    %al,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101ed3:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c0101ed7:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0101edb:	ee                   	out    %al,(%dx)
}
c0101edc:	90                   	nop
    outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF);
c0101edd:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101ee0:	c1 e8 08             	shr    $0x8,%eax
c0101ee3:	0f b6 c0             	movzbl %al,%eax
c0101ee6:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101eea:	83 c2 04             	add    $0x4,%edx
c0101eed:	0f b7 d2             	movzwl %dx,%edx
c0101ef0:	66 89 55 e2          	mov    %dx,-0x1e(%ebp)
c0101ef4:	88 45 e1             	mov    %al,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101ef7:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0101efb:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c0101eff:	ee                   	out    %al,(%dx)
}
c0101f00:	90                   	nop
    outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF);
c0101f01:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101f04:	c1 e8 10             	shr    $0x10,%eax
c0101f07:	0f b6 c0             	movzbl %al,%eax
c0101f0a:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101f0e:	83 c2 05             	add    $0x5,%edx
c0101f11:	0f b7 d2             	movzwl %dx,%edx
c0101f14:	66 89 55 e6          	mov    %dx,-0x1a(%ebp)
c0101f18:	88 45 e5             	mov    %al,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101f1b:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101f1f:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101f23:	ee                   	out    %al,(%dx)
}
c0101f24:	90                   	nop
    outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF));
c0101f25:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0101f28:	c0 e0 04             	shl    $0x4,%al
c0101f2b:	24 10                	and    $0x10,%al
c0101f2d:	88 c2                	mov    %al,%dl
c0101f2f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101f32:	c1 e8 18             	shr    $0x18,%eax
c0101f35:	24 0f                	and    $0xf,%al
c0101f37:	08 d0                	or     %dl,%al
c0101f39:	0c e0                	or     $0xe0,%al
c0101f3b:	0f b6 c0             	movzbl %al,%eax
c0101f3e:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101f42:	83 c2 06             	add    $0x6,%edx
c0101f45:	0f b7 d2             	movzwl %dx,%edx
c0101f48:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c0101f4c:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101f4f:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0101f53:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0101f57:	ee                   	out    %al,(%dx)
}
c0101f58:	90                   	nop
    outb(iobase + ISA_COMMAND, IDE_CMD_WRITE);
c0101f59:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101f5d:	83 c0 07             	add    $0x7,%eax
c0101f60:	0f b7 c0             	movzwl %ax,%eax
c0101f63:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101f67:	c6 45 ed 30          	movb   $0x30,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101f6b:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101f6f:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101f73:	ee                   	out    %al,(%dx)
}
c0101f74:	90                   	nop

    int ret = 0;
c0101f75:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    for (; nsecs > 0; nsecs --, src += SECTSIZE) {
c0101f7c:	eb 58                	jmp    c0101fd6 <ide_write_secs+0x22e>
        if ((ret = ide_wait_ready(iobase, 1)) != 0) {
c0101f7e:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101f82:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0101f89:	00 
c0101f8a:	89 04 24             	mov    %eax,(%esp)
c0101f8d:	e8 fa f7 ff ff       	call   c010178c <ide_wait_ready>
c0101f92:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0101f95:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0101f99:	75 43                	jne    c0101fde <ide_write_secs+0x236>
            goto out;
        }
        outsl(iobase, src, SECTSIZE / sizeof(uint32_t));
c0101f9b:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101f9f:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0101fa2:	8b 45 10             	mov    0x10(%ebp),%eax
c0101fa5:	89 45 cc             	mov    %eax,-0x34(%ebp)
c0101fa8:	c7 45 c8 80 00 00 00 	movl   $0x80,-0x38(%ebp)
    asm volatile (
c0101faf:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0101fb2:	8b 4d cc             	mov    -0x34(%ebp),%ecx
c0101fb5:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0101fb8:	89 cb                	mov    %ecx,%ebx
c0101fba:	89 de                	mov    %ebx,%esi
c0101fbc:	89 c1                	mov    %eax,%ecx
c0101fbe:	fc                   	cld    
c0101fbf:	f2 6f                	repnz outsl %ds:(%esi),(%dx)
c0101fc1:	89 c8                	mov    %ecx,%eax
c0101fc3:	89 f3                	mov    %esi,%ebx
c0101fc5:	89 5d cc             	mov    %ebx,-0x34(%ebp)
c0101fc8:	89 45 c8             	mov    %eax,-0x38(%ebp)
}
c0101fcb:	90                   	nop
    for (; nsecs > 0; nsecs --, src += SECTSIZE) {
c0101fcc:	ff 4d 14             	decl   0x14(%ebp)
c0101fcf:	81 45 10 00 02 00 00 	addl   $0x200,0x10(%ebp)
c0101fd6:	83 7d 14 00          	cmpl   $0x0,0x14(%ebp)
c0101fda:	75 a2                	jne    c0101f7e <ide_write_secs+0x1d6>
    }

out:
c0101fdc:	eb 01                	jmp    c0101fdf <ide_write_secs+0x237>
            goto out;
c0101fde:	90                   	nop
    return ret;
c0101fdf:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101fe2:	83 c4 50             	add    $0x50,%esp
c0101fe5:	5b                   	pop    %ebx
c0101fe6:	5e                   	pop    %esi
c0101fe7:	5d                   	pop    %ebp
c0101fe8:	c3                   	ret    

c0101fe9 <intr_enable>:
#include <x86.h>
#include <intr.h>

/* intr_enable - enable irq interrupt */
void
intr_enable(void) {
c0101fe9:	55                   	push   %ebp
c0101fea:	89 e5                	mov    %esp,%ebp
    asm volatile ("sti");
c0101fec:	fb                   	sti    
}
c0101fed:	90                   	nop
    sti();
}
c0101fee:	90                   	nop
c0101fef:	5d                   	pop    %ebp
c0101ff0:	c3                   	ret    

c0101ff1 <intr_disable>:

/* intr_disable - disable irq interrupt */
void
intr_disable(void) {
c0101ff1:	55                   	push   %ebp
c0101ff2:	89 e5                	mov    %esp,%ebp
    asm volatile ("cli" ::: "memory");
c0101ff4:	fa                   	cli    
}
c0101ff5:	90                   	nop
    cli();
}
c0101ff6:	90                   	nop
c0101ff7:	5d                   	pop    %ebp
c0101ff8:	c3                   	ret    

c0101ff9 <pic_setmask>:
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
static uint16_t irq_mask = 0xFFFF & ~(1 << IRQ_SLAVE);
static bool did_init = 0;

static void
pic_setmask(uint16_t mask) {
c0101ff9:	55                   	push   %ebp
c0101ffa:	89 e5                	mov    %esp,%ebp
c0101ffc:	83 ec 14             	sub    $0x14,%esp
c0101fff:	8b 45 08             	mov    0x8(%ebp),%eax
c0102002:	66 89 45 ec          	mov    %ax,-0x14(%ebp)
    irq_mask = mask;
c0102006:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0102009:	66 a3 50 f5 12 c0    	mov    %ax,0xc012f550
    if (did_init) {
c010200f:	a1 60 37 1a c0       	mov    0xc01a3760,%eax
c0102014:	85 c0                	test   %eax,%eax
c0102016:	74 39                	je     c0102051 <pic_setmask+0x58>
        outb(IO_PIC1 + 1, mask);
c0102018:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010201b:	0f b6 c0             	movzbl %al,%eax
c010201e:	66 c7 45 fa 21 00    	movw   $0x21,-0x6(%ebp)
c0102024:	88 45 f9             	mov    %al,-0x7(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102027:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c010202b:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c010202f:	ee                   	out    %al,(%dx)
}
c0102030:	90                   	nop
        outb(IO_PIC2 + 1, mask >> 8);
c0102031:	0f b7 45 ec          	movzwl -0x14(%ebp),%eax
c0102035:	c1 e8 08             	shr    $0x8,%eax
c0102038:	0f b7 c0             	movzwl %ax,%eax
c010203b:	0f b6 c0             	movzbl %al,%eax
c010203e:	66 c7 45 fe a1 00    	movw   $0xa1,-0x2(%ebp)
c0102044:	88 45 fd             	mov    %al,-0x3(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102047:	0f b6 45 fd          	movzbl -0x3(%ebp),%eax
c010204b:	0f b7 55 fe          	movzwl -0x2(%ebp),%edx
c010204f:	ee                   	out    %al,(%dx)
}
c0102050:	90                   	nop
    }
}
c0102051:	90                   	nop
c0102052:	89 ec                	mov    %ebp,%esp
c0102054:	5d                   	pop    %ebp
c0102055:	c3                   	ret    

c0102056 <pic_enable>:

void
pic_enable(unsigned int irq) {
c0102056:	55                   	push   %ebp
c0102057:	89 e5                	mov    %esp,%ebp
c0102059:	83 ec 04             	sub    $0x4,%esp
    pic_setmask(irq_mask & ~(1 << irq));
c010205c:	8b 45 08             	mov    0x8(%ebp),%eax
c010205f:	ba 01 00 00 00       	mov    $0x1,%edx
c0102064:	88 c1                	mov    %al,%cl
c0102066:	d3 e2                	shl    %cl,%edx
c0102068:	89 d0                	mov    %edx,%eax
c010206a:	98                   	cwtl   
c010206b:	f7 d0                	not    %eax
c010206d:	0f bf d0             	movswl %ax,%edx
c0102070:	0f b7 05 50 f5 12 c0 	movzwl 0xc012f550,%eax
c0102077:	98                   	cwtl   
c0102078:	21 d0                	and    %edx,%eax
c010207a:	98                   	cwtl   
c010207b:	0f b7 c0             	movzwl %ax,%eax
c010207e:	89 04 24             	mov    %eax,(%esp)
c0102081:	e8 73 ff ff ff       	call   c0101ff9 <pic_setmask>
}
c0102086:	90                   	nop
c0102087:	89 ec                	mov    %ebp,%esp
c0102089:	5d                   	pop    %ebp
c010208a:	c3                   	ret    

c010208b <pic_init>:

/* pic_init - initialize the 8259A interrupt controllers */
void
pic_init(void) {
c010208b:	55                   	push   %ebp
c010208c:	89 e5                	mov    %esp,%ebp
c010208e:	83 ec 44             	sub    $0x44,%esp
    did_init = 1;
c0102091:	c7 05 60 37 1a c0 01 	movl   $0x1,0xc01a3760
c0102098:	00 00 00 
c010209b:	66 c7 45 ca 21 00    	movw   $0x21,-0x36(%ebp)
c01020a1:	c6 45 c9 ff          	movb   $0xff,-0x37(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020a5:	0f b6 45 c9          	movzbl -0x37(%ebp),%eax
c01020a9:	0f b7 55 ca          	movzwl -0x36(%ebp),%edx
c01020ad:	ee                   	out    %al,(%dx)
}
c01020ae:	90                   	nop
c01020af:	66 c7 45 ce a1 00    	movw   $0xa1,-0x32(%ebp)
c01020b5:	c6 45 cd ff          	movb   $0xff,-0x33(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020b9:	0f b6 45 cd          	movzbl -0x33(%ebp),%eax
c01020bd:	0f b7 55 ce          	movzwl -0x32(%ebp),%edx
c01020c1:	ee                   	out    %al,(%dx)
}
c01020c2:	90                   	nop
c01020c3:	66 c7 45 d2 20 00    	movw   $0x20,-0x2e(%ebp)
c01020c9:	c6 45 d1 11          	movb   $0x11,-0x2f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020cd:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c01020d1:	0f b7 55 d2          	movzwl -0x2e(%ebp),%edx
c01020d5:	ee                   	out    %al,(%dx)
}
c01020d6:	90                   	nop
c01020d7:	66 c7 45 d6 21 00    	movw   $0x21,-0x2a(%ebp)
c01020dd:	c6 45 d5 20          	movb   $0x20,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020e1:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c01020e5:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c01020e9:	ee                   	out    %al,(%dx)
}
c01020ea:	90                   	nop
c01020eb:	66 c7 45 da 21 00    	movw   $0x21,-0x26(%ebp)
c01020f1:	c6 45 d9 04          	movb   $0x4,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020f5:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c01020f9:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c01020fd:	ee                   	out    %al,(%dx)
}
c01020fe:	90                   	nop
c01020ff:	66 c7 45 de 21 00    	movw   $0x21,-0x22(%ebp)
c0102105:	c6 45 dd 03          	movb   $0x3,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102109:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c010210d:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0102111:	ee                   	out    %al,(%dx)
}
c0102112:	90                   	nop
c0102113:	66 c7 45 e2 a0 00    	movw   $0xa0,-0x1e(%ebp)
c0102119:	c6 45 e1 11          	movb   $0x11,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010211d:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0102121:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c0102125:	ee                   	out    %al,(%dx)
}
c0102126:	90                   	nop
c0102127:	66 c7 45 e6 a1 00    	movw   $0xa1,-0x1a(%ebp)
c010212d:	c6 45 e5 28          	movb   $0x28,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102131:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0102135:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0102139:	ee                   	out    %al,(%dx)
}
c010213a:	90                   	nop
c010213b:	66 c7 45 ea a1 00    	movw   $0xa1,-0x16(%ebp)
c0102141:	c6 45 e9 02          	movb   $0x2,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102145:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0102149:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c010214d:	ee                   	out    %al,(%dx)
}
c010214e:	90                   	nop
c010214f:	66 c7 45 ee a1 00    	movw   $0xa1,-0x12(%ebp)
c0102155:	c6 45 ed 03          	movb   $0x3,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102159:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c010215d:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0102161:	ee                   	out    %al,(%dx)
}
c0102162:	90                   	nop
c0102163:	66 c7 45 f2 20 00    	movw   $0x20,-0xe(%ebp)
c0102169:	c6 45 f1 68          	movb   $0x68,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010216d:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0102171:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0102175:	ee                   	out    %al,(%dx)
}
c0102176:	90                   	nop
c0102177:	66 c7 45 f6 20 00    	movw   $0x20,-0xa(%ebp)
c010217d:	c6 45 f5 0a          	movb   $0xa,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102181:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c0102185:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0102189:	ee                   	out    %al,(%dx)
}
c010218a:	90                   	nop
c010218b:	66 c7 45 fa a0 00    	movw   $0xa0,-0x6(%ebp)
c0102191:	c6 45 f9 68          	movb   $0x68,-0x7(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102195:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c0102199:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c010219d:	ee                   	out    %al,(%dx)
}
c010219e:	90                   	nop
c010219f:	66 c7 45 fe a0 00    	movw   $0xa0,-0x2(%ebp)
c01021a5:	c6 45 fd 0a          	movb   $0xa,-0x3(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01021a9:	0f b6 45 fd          	movzbl -0x3(%ebp),%eax
c01021ad:	0f b7 55 fe          	movzwl -0x2(%ebp),%edx
c01021b1:	ee                   	out    %al,(%dx)
}
c01021b2:	90                   	nop
    outb(IO_PIC1, 0x0a);    // read IRR by default

    outb(IO_PIC2, 0x68);    // OCW3
    outb(IO_PIC2, 0x0a);    // OCW3

    if (irq_mask != 0xFFFF) {
c01021b3:	0f b7 05 50 f5 12 c0 	movzwl 0xc012f550,%eax
c01021ba:	3d ff ff 00 00       	cmp    $0xffff,%eax
c01021bf:	74 0f                	je     c01021d0 <pic_init+0x145>
        pic_setmask(irq_mask);
c01021c1:	0f b7 05 50 f5 12 c0 	movzwl 0xc012f550,%eax
c01021c8:	89 04 24             	mov    %eax,(%esp)
c01021cb:	e8 29 fe ff ff       	call   c0101ff9 <pic_setmask>
    }
}
c01021d0:	90                   	nop
c01021d1:	89 ec                	mov    %ebp,%esp
c01021d3:	5d                   	pop    %ebp
c01021d4:	c3                   	ret    

c01021d5 <print_ticks>:
#include <sched.h>
#include <sync.h>

#define TICK_NUM 100

static void print_ticks() {
c01021d5:	55                   	push   %ebp
c01021d6:	89 e5                	mov    %esp,%ebp
c01021d8:	83 ec 18             	sub    $0x18,%esp
    cprintf("%d ticks\n",TICK_NUM);
c01021db:	c7 44 24 04 64 00 00 	movl   $0x64,0x4(%esp)
c01021e2:	00 
c01021e3:	c7 04 24 c0 c3 10 c0 	movl   $0xc010c3c0,(%esp)
c01021ea:	e8 89 e1 ff ff       	call   c0100378 <cprintf>
#ifdef DEBUG_GRADE
    cprintf("End of Test.\n");
    panic("EOT: kernel seems ok.");//panic 是一个用于处理内核崩溃的函数，它会打印出错误信息并导致系统停止运行。
#endif
}
c01021ef:	90                   	nop
c01021f0:	89 ec                	mov    %ebp,%esp
c01021f2:	5d                   	pop    %ebp
c01021f3:	c3                   	ret    

c01021f4 <idt_init>:
    sizeof(idt) - 1, (uintptr_t)idt
};

/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void
idt_init(void) {
c01021f4:	55                   	push   %ebp
c01021f5:	89 e5                	mov    %esp,%ebp
c01021f7:	83 ec 10             	sub    $0x10,%esp
      *     You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more.
      *     Notice: the argument of lidt is idt_pd. try to find it!
      */
    extern uintptr_t __vectors[];//声明了一个外部数组 __vectors，该数组存储中断服务例程（ISR）的地址。
    int i;
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
c01021fa:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c0102201:	e9 c4 00 00 00       	jmp    c01022ca <idt_init+0xd6>
        SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
c0102206:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102209:	8b 04 85 e0 f5 12 c0 	mov    -0x3fed0a20(,%eax,4),%eax
c0102210:	0f b7 d0             	movzwl %ax,%edx
c0102213:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102216:	66 89 14 c5 80 37 1a 	mov    %dx,-0x3fe5c880(,%eax,8)
c010221d:	c0 
c010221e:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102221:	66 c7 04 c5 82 37 1a 	movw   $0x8,-0x3fe5c87e(,%eax,8)
c0102228:	c0 08 00 
c010222b:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010222e:	0f b6 14 c5 84 37 1a 	movzbl -0x3fe5c87c(,%eax,8),%edx
c0102235:	c0 
c0102236:	80 e2 e0             	and    $0xe0,%dl
c0102239:	88 14 c5 84 37 1a c0 	mov    %dl,-0x3fe5c87c(,%eax,8)
c0102240:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102243:	0f b6 14 c5 84 37 1a 	movzbl -0x3fe5c87c(,%eax,8),%edx
c010224a:	c0 
c010224b:	80 e2 1f             	and    $0x1f,%dl
c010224e:	88 14 c5 84 37 1a c0 	mov    %dl,-0x3fe5c87c(,%eax,8)
c0102255:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102258:	0f b6 14 c5 85 37 1a 	movzbl -0x3fe5c87b(,%eax,8),%edx
c010225f:	c0 
c0102260:	80 e2 f0             	and    $0xf0,%dl
c0102263:	80 ca 0e             	or     $0xe,%dl
c0102266:	88 14 c5 85 37 1a c0 	mov    %dl,-0x3fe5c87b(,%eax,8)
c010226d:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102270:	0f b6 14 c5 85 37 1a 	movzbl -0x3fe5c87b(,%eax,8),%edx
c0102277:	c0 
c0102278:	80 e2 ef             	and    $0xef,%dl
c010227b:	88 14 c5 85 37 1a c0 	mov    %dl,-0x3fe5c87b(,%eax,8)
c0102282:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102285:	0f b6 14 c5 85 37 1a 	movzbl -0x3fe5c87b(,%eax,8),%edx
c010228c:	c0 
c010228d:	80 e2 9f             	and    $0x9f,%dl
c0102290:	88 14 c5 85 37 1a c0 	mov    %dl,-0x3fe5c87b(,%eax,8)
c0102297:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010229a:	0f b6 14 c5 85 37 1a 	movzbl -0x3fe5c87b(,%eax,8),%edx
c01022a1:	c0 
c01022a2:	80 ca 80             	or     $0x80,%dl
c01022a5:	88 14 c5 85 37 1a c0 	mov    %dl,-0x3fe5c87b(,%eax,8)
c01022ac:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01022af:	8b 04 85 e0 f5 12 c0 	mov    -0x3fed0a20(,%eax,4),%eax
c01022b6:	c1 e8 10             	shr    $0x10,%eax
c01022b9:	0f b7 d0             	movzwl %ax,%edx
c01022bc:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01022bf:	66 89 14 c5 86 37 1a 	mov    %dx,-0x3fe5c87a(,%eax,8)
c01022c6:	c0 
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
c01022c7:	ff 45 fc             	incl   -0x4(%ebp)
c01022ca:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01022cd:	3d ff 00 00 00       	cmp    $0xff,%eax
c01022d2:	0f 86 2e ff ff ff    	jbe    c0102206 <idt_init+0x12>
    //宏用于配置每个 IDT 条目.0 表示最高特权级（内核级）GD_KTEXT: 指向内核代码段的选择子，确保 ISR 在内核代码段中执行。
	//__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级，表示该中断只能由内核级代码触发。
    // set for switch from user to kernel
    //SETGATE 这行代码特别设置了 T_SWITCH_TOK（一个特定的中断向量，用于用户态到内核态的切换）的 IDT 条目。
    //DPL_USER 表示该中断可以由用户态代码触发
    SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER);
c01022d8:	a1 e0 f7 12 c0       	mov    0xc012f7e0,%eax
c01022dd:	0f b7 c0             	movzwl %ax,%eax
c01022e0:	66 a3 80 3b 1a c0    	mov    %ax,0xc01a3b80
c01022e6:	66 c7 05 82 3b 1a c0 	movw   $0x8,0xc01a3b82
c01022ed:	08 00 
c01022ef:	0f b6 05 84 3b 1a c0 	movzbl 0xc01a3b84,%eax
c01022f6:	24 e0                	and    $0xe0,%al
c01022f8:	a2 84 3b 1a c0       	mov    %al,0xc01a3b84
c01022fd:	0f b6 05 84 3b 1a c0 	movzbl 0xc01a3b84,%eax
c0102304:	24 1f                	and    $0x1f,%al
c0102306:	a2 84 3b 1a c0       	mov    %al,0xc01a3b84
c010230b:	0f b6 05 85 3b 1a c0 	movzbl 0xc01a3b85,%eax
c0102312:	0c 0f                	or     $0xf,%al
c0102314:	a2 85 3b 1a c0       	mov    %al,0xc01a3b85
c0102319:	0f b6 05 85 3b 1a c0 	movzbl 0xc01a3b85,%eax
c0102320:	24 ef                	and    $0xef,%al
c0102322:	a2 85 3b 1a c0       	mov    %al,0xc01a3b85
c0102327:	0f b6 05 85 3b 1a c0 	movzbl 0xc01a3b85,%eax
c010232e:	0c 60                	or     $0x60,%al
c0102330:	a2 85 3b 1a c0       	mov    %al,0xc01a3b85
c0102335:	0f b6 05 85 3b 1a c0 	movzbl 0xc01a3b85,%eax
c010233c:	0c 80                	or     $0x80,%al
c010233e:	a2 85 3b 1a c0       	mov    %al,0xc01a3b85
c0102343:	a1 e0 f7 12 c0       	mov    0xc012f7e0,%eax
c0102348:	c1 e8 10             	shr    $0x10,%eax
c010234b:	0f b7 c0             	movzwl %ax,%eax
c010234e:	66 a3 86 3b 1a c0    	mov    %ax,0xc01a3b86
c0102354:	c7 45 f8 60 f5 12 c0 	movl   $0xc012f560,-0x8(%ebp)
    asm volatile ("lidt (%0)" :: "r" (pd) : "memory");
c010235b:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010235e:	0f 01 18             	lidtl  (%eax)
}
c0102361:	90                   	nop
    //使用 lidt 指令将 IDT 描述符加载到 CPU 中
    lidt(&idt_pd);
     /* LAB5 YOUR CODE */ 
     //you should update your lab1 code (just add ONE or TWO lines of code), let user app to use syscall to get the service of ucore
     //so you should setup the syscall interrupt gate in here
}
c0102362:	90                   	nop
c0102363:	89 ec                	mov    %ebp,%esp
c0102365:	5d                   	pop    %ebp
c0102366:	c3                   	ret    

c0102367 <trapname>:

static const char *
trapname(int trapno) {
c0102367:	55                   	push   %ebp
c0102368:	89 e5                	mov    %esp,%ebp
        "Alignment Check",
        "Machine-Check",
        "SIMD Floating-Point Exception"
    };
    //如果 trapno 小于数组长度，则返回对应的异常名称。
    if (trapno < sizeof(excnames)/sizeof(const char * const)) {
c010236a:	8b 45 08             	mov    0x8(%ebp),%eax
c010236d:	83 f8 13             	cmp    $0x13,%eax
c0102370:	77 0c                	ja     c010237e <trapname+0x17>
        return excnames[trapno];
c0102372:	8b 45 08             	mov    0x8(%ebp),%eax
c0102375:	8b 04 85 e0 c8 10 c0 	mov    -0x3fef3720(,%eax,4),%eax
c010237c:	eb 18                	jmp    c0102396 <trapname+0x2f>
    }
    //如果 trapno 在 IRQ_OFFSET 和 IRQ_OFFSET + 16 之间，表示它是一个硬件中断
    if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) {
c010237e:	83 7d 08 1f          	cmpl   $0x1f,0x8(%ebp)
c0102382:	7e 0d                	jle    c0102391 <trapname+0x2a>
c0102384:	83 7d 08 2f          	cmpl   $0x2f,0x8(%ebp)
c0102388:	7f 07                	jg     c0102391 <trapname+0x2a>
        return "Hardware Interrupt";
c010238a:	b8 ca c3 10 c0       	mov    $0xc010c3ca,%eax
c010238f:	eb 05                	jmp    c0102396 <trapname+0x2f>
    }
    return "(unknown trap)";
c0102391:	b8 dd c3 10 c0       	mov    $0xc010c3dd,%eax
}
c0102396:	5d                   	pop    %ebp
c0102397:	c3                   	ret    

c0102398 <trap_in_kernel>:

/* trap_in_kernel - test if trap happened in kernel */
bool
trap_in_kernel(struct trapframe *tf) {
c0102398:	55                   	push   %ebp
c0102399:	89 e5                	mov    %esp,%ebp
    return (tf->tf_cs == (uint16_t)KERNEL_CS);
c010239b:	8b 45 08             	mov    0x8(%ebp),%eax
c010239e:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c01023a2:	83 f8 08             	cmp    $0x8,%eax
c01023a5:	0f 94 c0             	sete   %al
c01023a8:	0f b6 c0             	movzbl %al,%eax
    //函数通过检查 tf 中的 tf_cs 字段来判断当前处于哪个特权级,tf_cs 存储了当前代码段选择子的值
    //当 tf->tf_cs 等于 KERNEL_CS 时，表示陷阱发生在内核模式下
}
c01023ab:	5d                   	pop    %ebp
c01023ac:	c3                   	ret    

c01023ad <print_trapframe>:
    "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL,
};

//struct trapframe *tf，一个指向 trapframe 结构的指针，包含有关陷阱发生时的 CPU 状态的信息。
void
print_trapframe(struct trapframe *tf) {
c01023ad:	55                   	push   %ebp
c01023ae:	89 e5                	mov    %esp,%ebp
c01023b0:	83 ec 28             	sub    $0x28,%esp
    cprintf("trapframe at %p\n", tf); //打印陷阱框架地址
c01023b3:	8b 45 08             	mov    0x8(%ebp),%eax
c01023b6:	89 44 24 04          	mov    %eax,0x4(%esp)
c01023ba:	c7 04 24 1e c4 10 c0 	movl   $0xc010c41e,(%esp)
c01023c1:	e8 b2 df ff ff       	call   c0100378 <cprintf>
    print_regs(&tf->tf_regs); //打印寄存器状态
c01023c6:	8b 45 08             	mov    0x8(%ebp),%eax
c01023c9:	89 04 24             	mov    %eax,(%esp)
c01023cc:	e8 8f 01 00 00       	call   c0102560 <print_regs>
    //打印数据段（DS）、扩展段（ES）、文件段（FS）、通用段（GS）的值。
    cprintf("  ds   0x----%04x\n", tf->tf_ds);
c01023d1:	8b 45 08             	mov    0x8(%ebp),%eax
c01023d4:	0f b7 40 2c          	movzwl 0x2c(%eax),%eax
c01023d8:	89 44 24 04          	mov    %eax,0x4(%esp)
c01023dc:	c7 04 24 2f c4 10 c0 	movl   $0xc010c42f,(%esp)
c01023e3:	e8 90 df ff ff       	call   c0100378 <cprintf>
    cprintf("  es   0x----%04x\n", tf->tf_es);
c01023e8:	8b 45 08             	mov    0x8(%ebp),%eax
c01023eb:	0f b7 40 28          	movzwl 0x28(%eax),%eax
c01023ef:	89 44 24 04          	mov    %eax,0x4(%esp)
c01023f3:	c7 04 24 42 c4 10 c0 	movl   $0xc010c442,(%esp)
c01023fa:	e8 79 df ff ff       	call   c0100378 <cprintf>
    cprintf("  fs   0x----%04x\n", tf->tf_fs);
c01023ff:	8b 45 08             	mov    0x8(%ebp),%eax
c0102402:	0f b7 40 24          	movzwl 0x24(%eax),%eax
c0102406:	89 44 24 04          	mov    %eax,0x4(%esp)
c010240a:	c7 04 24 55 c4 10 c0 	movl   $0xc010c455,(%esp)
c0102411:	e8 62 df ff ff       	call   c0100378 <cprintf>
    cprintf("  gs   0x----%04x\n", tf->tf_gs);
c0102416:	8b 45 08             	mov    0x8(%ebp),%eax
c0102419:	0f b7 40 20          	movzwl 0x20(%eax),%eax
c010241d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102421:	c7 04 24 68 c4 10 c0 	movl   $0xc010c468,(%esp)
c0102428:	e8 4b df ff ff       	call   c0100378 <cprintf>
    // 打印陷阱号（trap number）及其对应的名称，通过调用 trapname 函数获取。
    cprintf("  trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
c010242d:	8b 45 08             	mov    0x8(%ebp),%eax
c0102430:	8b 40 30             	mov    0x30(%eax),%eax
c0102433:	89 04 24             	mov    %eax,(%esp)
c0102436:	e8 2c ff ff ff       	call   c0102367 <trapname>
c010243b:	8b 55 08             	mov    0x8(%ebp),%edx
c010243e:	8b 52 30             	mov    0x30(%edx),%edx
c0102441:	89 44 24 08          	mov    %eax,0x8(%esp)
c0102445:	89 54 24 04          	mov    %edx,0x4(%esp)
c0102449:	c7 04 24 7b c4 10 c0 	movl   $0xc010c47b,(%esp)
c0102450:	e8 23 df ff ff       	call   c0100378 <cprintf>
    cprintf("  err  0x%08x\n", tf->tf_err);// 如果有错误代码，打印该字段的值。
c0102455:	8b 45 08             	mov    0x8(%ebp),%eax
c0102458:	8b 40 34             	mov    0x34(%eax),%eax
c010245b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010245f:	c7 04 24 8d c4 10 c0 	movl   $0xc010c48d,(%esp)
c0102466:	e8 0d df ff ff       	call   c0100378 <cprintf>
    cprintf("  eip  0x%08x\n", tf->tf_eip);//打印当前执行的指令指针（EIP），指向出错或中断的指令。
c010246b:	8b 45 08             	mov    0x8(%ebp),%eax
c010246e:	8b 40 38             	mov    0x38(%eax),%eax
c0102471:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102475:	c7 04 24 9c c4 10 c0 	movl   $0xc010c49c,(%esp)
c010247c:	e8 f7 de ff ff       	call   c0100378 <cprintf>
    cprintf("  cs   0x----%04x\n", tf->tf_cs);//打印代码段寄存器（CS）的值。
c0102481:	8b 45 08             	mov    0x8(%ebp),%eax
c0102484:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c0102488:	89 44 24 04          	mov    %eax,0x4(%esp)
c010248c:	c7 04 24 ab c4 10 c0 	movl   $0xc010c4ab,(%esp)
c0102493:	e8 e0 de ff ff       	call   c0100378 <cprintf>
    cprintf("  flag 0x%08x ", tf->tf_eflags);// 打印标志寄存器（EFLAGS）的值
c0102498:	8b 45 08             	mov    0x8(%ebp),%eax
c010249b:	8b 40 40             	mov    0x40(%eax),%eax
c010249e:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024a2:	c7 04 24 be c4 10 c0 	movl   $0xc010c4be,(%esp)
c01024a9:	e8 ca de ff ff       	call   c0100378 <cprintf>
    //使用循环遍历 IA32flags 数组，j 表示当前标志位的位掩码。
    int i, j;
    for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) {
c01024ae:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c01024b5:	c7 45 f0 01 00 00 00 	movl   $0x1,-0x10(%ebp)
c01024bc:	eb 3d                	jmp    c01024fb <print_trapframe+0x14e>
        if ((tf->tf_eflags & j) && IA32flags[i] != NULL) {
c01024be:	8b 45 08             	mov    0x8(%ebp),%eax
c01024c1:	8b 50 40             	mov    0x40(%eax),%edx
c01024c4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01024c7:	21 d0                	and    %edx,%eax
c01024c9:	85 c0                	test   %eax,%eax
c01024cb:	74 28                	je     c01024f5 <print_trapframe+0x148>
c01024cd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01024d0:	8b 04 85 80 f5 12 c0 	mov    -0x3fed0a80(,%eax,4),%eax
c01024d7:	85 c0                	test   %eax,%eax
c01024d9:	74 1a                	je     c01024f5 <print_trapframe+0x148>
            cprintf("%s,", IA32flags[i]);
c01024db:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01024de:	8b 04 85 80 f5 12 c0 	mov    -0x3fed0a80(,%eax,4),%eax
c01024e5:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024e9:	c7 04 24 cd c4 10 c0 	movl   $0xc010c4cd,(%esp)
c01024f0:	e8 83 de ff ff       	call   c0100378 <cprintf>
    for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) {
c01024f5:	ff 45 f4             	incl   -0xc(%ebp)
c01024f8:	d1 65 f0             	shll   -0x10(%ebp)
c01024fb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01024fe:	83 f8 17             	cmp    $0x17,%eax
c0102501:	76 bb                	jbe    c01024be <print_trapframe+0x111>
        }
    }
    //通过位掩码 FL_IOPL_MASK 获取和打印当前的 I/O 特权级别。
    cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12);
c0102503:	8b 45 08             	mov    0x8(%ebp),%eax
c0102506:	8b 40 40             	mov    0x40(%eax),%eax
c0102509:	c1 e8 0c             	shr    $0xc,%eax
c010250c:	83 e0 03             	and    $0x3,%eax
c010250f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102513:	c7 04 24 d1 c4 10 c0 	movl   $0xc010c4d1,(%esp)
c010251a:	e8 59 de ff ff       	call   c0100378 <cprintf>
    //如果陷阱不是在内核中发生的（通过 trap_in_kernel 判断），
    //则打印栈指针（ESP）和栈段（SS）寄存器的值。
    if (!trap_in_kernel(tf)) {
c010251f:	8b 45 08             	mov    0x8(%ebp),%eax
c0102522:	89 04 24             	mov    %eax,(%esp)
c0102525:	e8 6e fe ff ff       	call   c0102398 <trap_in_kernel>
c010252a:	85 c0                	test   %eax,%eax
c010252c:	75 2d                	jne    c010255b <print_trapframe+0x1ae>
        cprintf("  esp  0x%08x\n", tf->tf_esp);
c010252e:	8b 45 08             	mov    0x8(%ebp),%eax
c0102531:	8b 40 44             	mov    0x44(%eax),%eax
c0102534:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102538:	c7 04 24 da c4 10 c0 	movl   $0xc010c4da,(%esp)
c010253f:	e8 34 de ff ff       	call   c0100378 <cprintf>
        cprintf("  ss   0x----%04x\n", tf->tf_ss);
c0102544:	8b 45 08             	mov    0x8(%ebp),%eax
c0102547:	0f b7 40 48          	movzwl 0x48(%eax),%eax
c010254b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010254f:	c7 04 24 e9 c4 10 c0 	movl   $0xc010c4e9,(%esp)
c0102556:	e8 1d de ff ff       	call   c0100378 <cprintf>
    }
}
c010255b:	90                   	nop
c010255c:	89 ec                	mov    %ebp,%esp
c010255e:	5d                   	pop    %ebp
c010255f:	c3                   	ret    

c0102560 <print_regs>:
//定义了一个名为 print_regs 的函数，
//打印出存储在 struct pushregs 结构体中的寄存器值。
void
print_regs(struct pushregs *regs) {
c0102560:	55                   	push   %ebp
c0102561:	89 e5                	mov    %esp,%ebp
c0102563:	83 ec 18             	sub    $0x18,%esp
    cprintf("  edi  0x%08x\n", regs->reg_edi);
c0102566:	8b 45 08             	mov    0x8(%ebp),%eax
c0102569:	8b 00                	mov    (%eax),%eax
c010256b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010256f:	c7 04 24 fc c4 10 c0 	movl   $0xc010c4fc,(%esp)
c0102576:	e8 fd dd ff ff       	call   c0100378 <cprintf>
    cprintf("  esi  0x%08x\n", regs->reg_esi);
c010257b:	8b 45 08             	mov    0x8(%ebp),%eax
c010257e:	8b 40 04             	mov    0x4(%eax),%eax
c0102581:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102585:	c7 04 24 0b c5 10 c0 	movl   $0xc010c50b,(%esp)
c010258c:	e8 e7 dd ff ff       	call   c0100378 <cprintf>
    cprintf("  ebp  0x%08x\n", regs->reg_ebp);
c0102591:	8b 45 08             	mov    0x8(%ebp),%eax
c0102594:	8b 40 08             	mov    0x8(%eax),%eax
c0102597:	89 44 24 04          	mov    %eax,0x4(%esp)
c010259b:	c7 04 24 1a c5 10 c0 	movl   $0xc010c51a,(%esp)
c01025a2:	e8 d1 dd ff ff       	call   c0100378 <cprintf>
    cprintf("  oesp 0x%08x\n", regs->reg_oesp);//打印旧的栈指针（OESP），这个寄存器通常在陷阱或中断发生时用于记录上一个栈指针。
c01025a7:	8b 45 08             	mov    0x8(%ebp),%eax
c01025aa:	8b 40 0c             	mov    0xc(%eax),%eax
c01025ad:	89 44 24 04          	mov    %eax,0x4(%esp)
c01025b1:	c7 04 24 29 c5 10 c0 	movl   $0xc010c529,(%esp)
c01025b8:	e8 bb dd ff ff       	call   c0100378 <cprintf>
    cprintf("  ebx  0x%08x\n", regs->reg_ebx);
c01025bd:	8b 45 08             	mov    0x8(%ebp),%eax
c01025c0:	8b 40 10             	mov    0x10(%eax),%eax
c01025c3:	89 44 24 04          	mov    %eax,0x4(%esp)
c01025c7:	c7 04 24 38 c5 10 c0 	movl   $0xc010c538,(%esp)
c01025ce:	e8 a5 dd ff ff       	call   c0100378 <cprintf>
    cprintf("  edx  0x%08x\n", regs->reg_edx);
c01025d3:	8b 45 08             	mov    0x8(%ebp),%eax
c01025d6:	8b 40 14             	mov    0x14(%eax),%eax
c01025d9:	89 44 24 04          	mov    %eax,0x4(%esp)
c01025dd:	c7 04 24 47 c5 10 c0 	movl   $0xc010c547,(%esp)
c01025e4:	e8 8f dd ff ff       	call   c0100378 <cprintf>
    cprintf("  ecx  0x%08x\n", regs->reg_ecx);
c01025e9:	8b 45 08             	mov    0x8(%ebp),%eax
c01025ec:	8b 40 18             	mov    0x18(%eax),%eax
c01025ef:	89 44 24 04          	mov    %eax,0x4(%esp)
c01025f3:	c7 04 24 56 c5 10 c0 	movl   $0xc010c556,(%esp)
c01025fa:	e8 79 dd ff ff       	call   c0100378 <cprintf>
    cprintf("  eax  0x%08x\n", regs->reg_eax);
c01025ff:	8b 45 08             	mov    0x8(%ebp),%eax
c0102602:	8b 40 1c             	mov    0x1c(%eax),%eax
c0102605:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102609:	c7 04 24 65 c5 10 c0 	movl   $0xc010c565,(%esp)
c0102610:	e8 63 dd ff ff       	call   c0100378 <cprintf>
}
c0102615:	90                   	nop
c0102616:	89 ec                	mov    %ebp,%esp
c0102618:	5d                   	pop    %ebp
c0102619:	c3                   	ret    

c010261a <print_pgfault>:

static inline void
print_pgfault(struct trapframe *tf) {
c010261a:	55                   	push   %ebp
c010261b:	89 e5                	mov    %esp,%ebp
c010261d:	83 ec 38             	sub    $0x38,%esp
c0102620:	89 5d fc             	mov    %ebx,-0x4(%ebp)
     * bit 2 == 0 表示内核模式，1 表示用户模式
     * */
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
            (tf->tf_err & 4) ? 'U' : 'K',
            (tf->tf_err & 2) ? 'W' : 'R',
            (tf->tf_err & 1) ? "protection fault" : "no page found");
c0102623:	8b 45 08             	mov    0x8(%ebp),%eax
c0102626:	8b 40 34             	mov    0x34(%eax),%eax
c0102629:	83 e0 01             	and    $0x1,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c010262c:	85 c0                	test   %eax,%eax
c010262e:	74 07                	je     c0102637 <print_pgfault+0x1d>
c0102630:	bb 74 c5 10 c0       	mov    $0xc010c574,%ebx
c0102635:	eb 05                	jmp    c010263c <print_pgfault+0x22>
c0102637:	bb 85 c5 10 c0       	mov    $0xc010c585,%ebx
            (tf->tf_err & 2) ? 'W' : 'R',
c010263c:	8b 45 08             	mov    0x8(%ebp),%eax
c010263f:	8b 40 34             	mov    0x34(%eax),%eax
c0102642:	83 e0 02             	and    $0x2,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c0102645:	85 c0                	test   %eax,%eax
c0102647:	74 07                	je     c0102650 <print_pgfault+0x36>
c0102649:	b9 57 00 00 00       	mov    $0x57,%ecx
c010264e:	eb 05                	jmp    c0102655 <print_pgfault+0x3b>
c0102650:	b9 52 00 00 00       	mov    $0x52,%ecx
            (tf->tf_err & 4) ? 'U' : 'K',
c0102655:	8b 45 08             	mov    0x8(%ebp),%eax
c0102658:	8b 40 34             	mov    0x34(%eax),%eax
c010265b:	83 e0 04             	and    $0x4,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c010265e:	85 c0                	test   %eax,%eax
c0102660:	74 07                	je     c0102669 <print_pgfault+0x4f>
c0102662:	ba 55 00 00 00       	mov    $0x55,%edx
c0102667:	eb 05                	jmp    c010266e <print_pgfault+0x54>
c0102669:	ba 4b 00 00 00       	mov    $0x4b,%edx
}

static inline uintptr_t
rcr2(void) {
    uintptr_t cr2;
    asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory");
c010266e:	0f 20 d0             	mov    %cr2,%eax
c0102671:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return cr2;
c0102674:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0102677:	89 5c 24 10          	mov    %ebx,0x10(%esp)
c010267b:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c010267f:	89 54 24 08          	mov    %edx,0x8(%esp)
c0102683:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102687:	c7 04 24 94 c5 10 c0 	movl   $0xc010c594,(%esp)
c010268e:	e8 e5 dc ff ff       	call   c0100378 <cprintf>
}
c0102693:	90                   	nop
c0102694:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c0102697:	89 ec                	mov    %ebp,%esp
c0102699:	5d                   	pop    %ebp
c010269a:	c3                   	ret    

c010269b <pgfault_handler>:

static int
pgfault_handler(struct trapframe *tf) {
c010269b:	55                   	push   %ebp
c010269c:	89 e5                	mov    %esp,%ebp
c010269e:	83 ec 28             	sub    $0x28,%esp
    extern struct mm_struct *check_mm_struct;
    if(check_mm_struct !=NULL) { //used for test check_swap
c01026a1:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c01026a6:	85 c0                	test   %eax,%eax
c01026a8:	74 0b                	je     c01026b5 <pgfault_handler+0x1a>
            print_pgfault(tf);
c01026aa:	8b 45 08             	mov    0x8(%ebp),%eax
c01026ad:	89 04 24             	mov    %eax,(%esp)
c01026b0:	e8 65 ff ff ff       	call   c010261a <print_pgfault>
        }
    struct mm_struct *mm;
    if (check_mm_struct != NULL) {
c01026b5:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c01026ba:	85 c0                	test   %eax,%eax
c01026bc:	74 3d                	je     c01026fb <pgfault_handler+0x60>
        assert(current == idleproc);
c01026be:	8b 15 30 41 1a c0    	mov    0xc01a4130,%edx
c01026c4:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c01026c9:	39 c2                	cmp    %eax,%edx
c01026cb:	74 24                	je     c01026f1 <pgfault_handler+0x56>
c01026cd:	c7 44 24 0c b7 c5 10 	movl   $0xc010c5b7,0xc(%esp)
c01026d4:	c0 
c01026d5:	c7 44 24 08 cb c5 10 	movl   $0xc010c5cb,0x8(%esp)
c01026dc:	c0 
c01026dd:	c7 44 24 04 c7 00 00 	movl   $0xc7,0x4(%esp)
c01026e4:	00 
c01026e5:	c7 04 24 e0 c5 10 c0 	movl   $0xc010c5e0,(%esp)
c01026ec:	e8 4a e6 ff ff       	call   c0100d3b <__panic>
        mm = check_mm_struct;
c01026f1:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c01026f6:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01026f9:	eb 46                	jmp    c0102741 <pgfault_handler+0xa6>
    }
    else {
        if (current == NULL) {
c01026fb:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c0102700:	85 c0                	test   %eax,%eax
c0102702:	75 32                	jne    c0102736 <pgfault_handler+0x9b>
            print_trapframe(tf);
c0102704:	8b 45 08             	mov    0x8(%ebp),%eax
c0102707:	89 04 24             	mov    %eax,(%esp)
c010270a:	e8 9e fc ff ff       	call   c01023ad <print_trapframe>
            print_pgfault(tf);
c010270f:	8b 45 08             	mov    0x8(%ebp),%eax
c0102712:	89 04 24             	mov    %eax,(%esp)
c0102715:	e8 00 ff ff ff       	call   c010261a <print_pgfault>
            panic("unhandled page fault.\n");
c010271a:	c7 44 24 08 f1 c5 10 	movl   $0xc010c5f1,0x8(%esp)
c0102721:	c0 
c0102722:	c7 44 24 04 ce 00 00 	movl   $0xce,0x4(%esp)
c0102729:	00 
c010272a:	c7 04 24 e0 c5 10 c0 	movl   $0xc010c5e0,(%esp)
c0102731:	e8 05 e6 ff ff       	call   c0100d3b <__panic>
        }
        mm = current->mm;
c0102736:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010273b:	8b 40 18             	mov    0x18(%eax),%eax
c010273e:	89 45 f4             	mov    %eax,-0xc(%ebp)
    asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory");
c0102741:	0f 20 d0             	mov    %cr2,%eax
c0102744:	89 45 f0             	mov    %eax,-0x10(%ebp)
    return cr2;
c0102747:	8b 55 f0             	mov    -0x10(%ebp),%edx
    }
    return do_pgfault(mm, tf->tf_err, rcr2());
c010274a:	8b 45 08             	mov    0x8(%ebp),%eax
c010274d:	8b 40 34             	mov    0x34(%eax),%eax
c0102750:	89 54 24 08          	mov    %edx,0x8(%esp)
c0102754:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102758:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010275b:	89 04 24             	mov    %eax,(%esp)
c010275e:	e8 e0 66 00 00       	call   c0108e43 <do_pgfault>
}
c0102763:	89 ec                	mov    %ebp,%esp
c0102765:	5d                   	pop    %ebp
c0102766:	c3                   	ret    

c0102767 <trap_dispatch>:

static volatile int in_swap_tick_event = 0;
extern struct mm_struct *check_mm_struct;

static void
trap_dispatch(struct trapframe *tf) {
c0102767:	55                   	push   %ebp
c0102768:	89 e5                	mov    %esp,%ebp
c010276a:	83 ec 28             	sub    $0x28,%esp
    char c;

    int ret=0;
c010276d:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)

    switch (tf->tf_trapno) {
c0102774:	8b 45 08             	mov    0x8(%ebp),%eax
c0102777:	8b 40 30             	mov    0x30(%eax),%eax
c010277a:	3d 80 00 00 00       	cmp    $0x80,%eax
c010277f:	0f 84 ef 00 00 00    	je     c0102874 <trap_dispatch+0x10d>
c0102785:	3d 80 00 00 00       	cmp    $0x80,%eax
c010278a:	0f 87 d3 01 00 00    	ja     c0102963 <trap_dispatch+0x1fc>
c0102790:	83 f8 2f             	cmp    $0x2f,%eax
c0102793:	77 1e                	ja     c01027b3 <trap_dispatch+0x4c>
c0102795:	83 f8 0e             	cmp    $0xe,%eax
c0102798:	0f 82 c5 01 00 00    	jb     c0102963 <trap_dispatch+0x1fc>
c010279e:	83 e8 0e             	sub    $0xe,%eax
c01027a1:	83 f8 21             	cmp    $0x21,%eax
c01027a4:	0f 87 b9 01 00 00    	ja     c0102963 <trap_dispatch+0x1fc>
c01027aa:	8b 04 85 04 c7 10 c0 	mov    -0x3fef38fc(,%eax,4),%eax
c01027b1:	ff e0                	jmp    *%eax
c01027b3:	83 e8 78             	sub    $0x78,%eax
c01027b6:	83 f8 01             	cmp    $0x1,%eax
c01027b9:	0f 87 a4 01 00 00    	ja     c0102963 <trap_dispatch+0x1fc>
c01027bf:	e9 83 01 00 00       	jmp    c0102947 <trap_dispatch+0x1e0>
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
c01027c4:	8b 45 08             	mov    0x8(%ebp),%eax
c01027c7:	89 04 24             	mov    %eax,(%esp)
c01027ca:	e8 cc fe ff ff       	call   c010269b <pgfault_handler>
c01027cf:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01027d2:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01027d6:	0f 84 d2 01 00 00    	je     c01029ae <trap_dispatch+0x247>
            print_trapframe(tf);
c01027dc:	8b 45 08             	mov    0x8(%ebp),%eax
c01027df:	89 04 24             	mov    %eax,(%esp)
c01027e2:	e8 c6 fb ff ff       	call   c01023ad <print_trapframe>
            if (current == NULL) {
c01027e7:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01027ec:	85 c0                	test   %eax,%eax
c01027ee:	75 23                	jne    c0102813 <trap_dispatch+0xac>
                panic("handle pgfault failed. ret=%d\n", ret);
c01027f0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01027f3:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01027f7:	c7 44 24 08 08 c6 10 	movl   $0xc010c608,0x8(%esp)
c01027fe:	c0 
c01027ff:	c7 44 24 04 e3 00 00 	movl   $0xe3,0x4(%esp)
c0102806:	00 
c0102807:	c7 04 24 e0 c5 10 c0 	movl   $0xc010c5e0,(%esp)
c010280e:	e8 28 e5 ff ff       	call   c0100d3b <__panic>
            }
            else {
                if (trap_in_kernel(tf)) {
c0102813:	8b 45 08             	mov    0x8(%ebp),%eax
c0102816:	89 04 24             	mov    %eax,(%esp)
c0102819:	e8 7a fb ff ff       	call   c0102398 <trap_in_kernel>
c010281e:	85 c0                	test   %eax,%eax
c0102820:	74 23                	je     c0102845 <trap_dispatch+0xde>
                    panic("handle pgfault failed in kernel mode. ret=%d\n", ret);
c0102822:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0102825:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0102829:	c7 44 24 08 28 c6 10 	movl   $0xc010c628,0x8(%esp)
c0102830:	c0 
c0102831:	c7 44 24 04 e7 00 00 	movl   $0xe7,0x4(%esp)
c0102838:	00 
c0102839:	c7 04 24 e0 c5 10 c0 	movl   $0xc010c5e0,(%esp)
c0102840:	e8 f6 e4 ff ff       	call   c0100d3b <__panic>
                }
                cprintf("killed by kernel.\n");
c0102845:	c7 04 24 56 c6 10 c0 	movl   $0xc010c656,(%esp)
c010284c:	e8 27 db ff ff       	call   c0100378 <cprintf>
                panic("handle user mode pgfault failed. ret=%d\n", ret); 
c0102851:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0102854:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0102858:	c7 44 24 08 6c c6 10 	movl   $0xc010c66c,0x8(%esp)
c010285f:	c0 
c0102860:	c7 44 24 04 ea 00 00 	movl   $0xea,0x4(%esp)
c0102867:	00 
c0102868:	c7 04 24 e0 c5 10 c0 	movl   $0xc010c5e0,(%esp)
c010286f:	e8 c7 e4 ff ff       	call   c0100d3b <__panic>
                do_exit(-E_KILLED);
            }
        }
        break;
    case T_SYSCALL:
        syscall();
c0102874:	e8 13 8a 00 00       	call   c010b28c <syscall>
        break;
c0102879:	e9 34 01 00 00       	jmp    c01029b2 <trap_dispatch+0x24b>
         */
        /* LAB5 YOUR CODE */
        /* you should upate you lab1 code (just add ONE or TWO lines of code):
         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
         */
        ticks ++; //记录中断事件
c010287e:	a1 24 34 1a c0       	mov    0xc01a3424,%eax
c0102883:	40                   	inc    %eax
c0102884:	a3 24 34 1a c0       	mov    %eax,0xc01a3424
        if (ticks % TICK_NUM == 0)
c0102889:	8b 0d 24 34 1a c0    	mov    0xc01a3424,%ecx
c010288f:	ba 1f 85 eb 51       	mov    $0x51eb851f,%edx
c0102894:	89 c8                	mov    %ecx,%eax
c0102896:	f7 e2                	mul    %edx
c0102898:	c1 ea 05             	shr    $0x5,%edx
c010289b:	89 d0                	mov    %edx,%eax
c010289d:	c1 e0 02             	shl    $0x2,%eax
c01028a0:	01 d0                	add    %edx,%eax
c01028a2:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c01028a9:	01 d0                	add    %edx,%eax
c01028ab:	c1 e0 02             	shl    $0x2,%eax
c01028ae:	29 c1                	sub    %eax,%ecx
c01028b0:	89 ca                	mov    %ecx,%edx
c01028b2:	85 d2                	test   %edx,%edx
c01028b4:	0f 85 f7 00 00 00    	jne    c01029b1 <trap_dispatch+0x24a>
        {
            assert(current != NULL);
c01028ba:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01028bf:	85 c0                	test   %eax,%eax
c01028c1:	75 24                	jne    c01028e7 <trap_dispatch+0x180>
c01028c3:	c7 44 24 0c 95 c6 10 	movl   $0xc010c695,0xc(%esp)
c01028ca:	c0 
c01028cb:	c7 44 24 08 cb c5 10 	movl   $0xc010c5cb,0x8(%esp)
c01028d2:	c0 
c01028d3:	c7 44 24 04 04 01 00 	movl   $0x104,0x4(%esp)
c01028da:	00 
c01028db:	c7 04 24 e0 c5 10 c0 	movl   $0xc010c5e0,(%esp)
c01028e2:	e8 54 e4 ff ff       	call   c0100d3b <__panic>
            current->need_resched = 1;
c01028e7:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01028ec:	c7 40 10 01 00 00 00 	movl   $0x1,0x10(%eax)
        }//每经过 TICK_NUM 次周期时，调用 print_ticks() 打印信息
        break;
c01028f3:	e9 b9 00 00 00       	jmp    c01029b1 <trap_dispatch+0x24a>
    case IRQ_OFFSET + IRQ_COM1:
        c = cons_getc();
c01028f8:	e8 1e ee ff ff       	call   c010171b <cons_getc>
c01028fd:	88 45 f3             	mov    %al,-0xd(%ebp)
        cprintf("serial [%03d] %c\n", c, c);
c0102900:	0f be 55 f3          	movsbl -0xd(%ebp),%edx
c0102904:	0f be 45 f3          	movsbl -0xd(%ebp),%eax
c0102908:	89 54 24 08          	mov    %edx,0x8(%esp)
c010290c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102910:	c7 04 24 a5 c6 10 c0 	movl   $0xc010c6a5,(%esp)
c0102917:	e8 5c da ff ff       	call   c0100378 <cprintf>
        break;
c010291c:	e9 91 00 00 00       	jmp    c01029b2 <trap_dispatch+0x24b>
    case IRQ_OFFSET + IRQ_KBD:
        c = cons_getc();
c0102921:	e8 f5 ed ff ff       	call   c010171b <cons_getc>
c0102926:	88 45 f3             	mov    %al,-0xd(%ebp)
        cprintf("kbd [%03d] %c\n", c, c);
c0102929:	0f be 55 f3          	movsbl -0xd(%ebp),%edx
c010292d:	0f be 45 f3          	movsbl -0xd(%ebp),%eax
c0102931:	89 54 24 08          	mov    %edx,0x8(%esp)
c0102935:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102939:	c7 04 24 b7 c6 10 c0 	movl   $0xc010c6b7,(%esp)
c0102940:	e8 33 da ff ff       	call   c0100378 <cprintf>
        break;
c0102945:	eb 6b                	jmp    c01029b2 <trap_dispatch+0x24b>
    //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
    case T_SWITCH_TOU:
    case T_SWITCH_TOK:
        panic("T_SWITCH_** ??\n");
c0102947:	c7 44 24 08 c6 c6 10 	movl   $0xc010c6c6,0x8(%esp)
c010294e:	c0 
c010294f:	c7 44 24 04 13 01 00 	movl   $0x113,0x4(%esp)
c0102956:	00 
c0102957:	c7 04 24 e0 c5 10 c0 	movl   $0xc010c5e0,(%esp)
c010295e:	e8 d8 e3 ff ff       	call   c0100d3b <__panic>
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        print_trapframe(tf);
c0102963:	8b 45 08             	mov    0x8(%ebp),%eax
c0102966:	89 04 24             	mov    %eax,(%esp)
c0102969:	e8 3f fa ff ff       	call   c01023ad <print_trapframe>
        if (current != NULL) {
c010296e:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c0102973:	85 c0                	test   %eax,%eax
c0102975:	74 18                	je     c010298f <trap_dispatch+0x228>
            cprintf("unhandled trap.\n");
c0102977:	c7 04 24 d6 c6 10 c0 	movl   $0xc010c6d6,(%esp)
c010297e:	e8 f5 d9 ff ff       	call   c0100378 <cprintf>
            do_exit(-E_KILLED);
c0102983:	c7 04 24 f7 ff ff ff 	movl   $0xfffffff7,(%esp)
c010298a:	e8 81 76 00 00       	call   c010a010 <do_exit>
        }
        // in kernel, it must be a mistake
        panic("unexpected trap in kernel.\n");
c010298f:	c7 44 24 08 e7 c6 10 	movl   $0xc010c6e7,0x8(%esp)
c0102996:	c0 
c0102997:	c7 44 24 04 20 01 00 	movl   $0x120,0x4(%esp)
c010299e:	00 
c010299f:	c7 04 24 e0 c5 10 c0 	movl   $0xc010c5e0,(%esp)
c01029a6:	e8 90 e3 ff ff       	call   c0100d3b <__panic>
        break;
c01029ab:	90                   	nop
c01029ac:	eb 04                	jmp    c01029b2 <trap_dispatch+0x24b>
        break;
c01029ae:	90                   	nop
c01029af:	eb 01                	jmp    c01029b2 <trap_dispatch+0x24b>
        break;
c01029b1:	90                   	nop

    }
}
c01029b2:	90                   	nop
c01029b3:	89 ec                	mov    %ebp,%esp
c01029b5:	5d                   	pop    %ebp
c01029b6:	c3                   	ret    

c01029b7 <trap>:
 * trap - handles or dispatches an exception/interrupt. if and when trap() returns,
 * the code in kern/trap/trapentry.S restores the old CPU state saved in the
 * trapframe and then uses the iret instruction to return from the exception.
 * */
void
trap(struct trapframe *tf) {
c01029b7:	55                   	push   %ebp
c01029b8:	89 e5                	mov    %esp,%ebp
c01029ba:	83 ec 28             	sub    $0x28,%esp
    // dispatch based on what type of trap occurred
    // used for previous projects
    if (current == NULL) {
c01029bd:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01029c2:	85 c0                	test   %eax,%eax
c01029c4:	75 0d                	jne    c01029d3 <trap+0x1c>
        trap_dispatch(tf);
c01029c6:	8b 45 08             	mov    0x8(%ebp),%eax
c01029c9:	89 04 24             	mov    %eax,(%esp)
c01029cc:	e8 96 fd ff ff       	call   c0102767 <trap_dispatch>
            if (current->need_resched) {
                schedule();
            }
        }
    }
}
c01029d1:	eb 6c                	jmp    c0102a3f <trap+0x88>
        struct trapframe *otf = current->tf;
c01029d3:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01029d8:	8b 40 3c             	mov    0x3c(%eax),%eax
c01029db:	89 45 f4             	mov    %eax,-0xc(%ebp)
        current->tf = tf;
c01029de:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01029e3:	8b 55 08             	mov    0x8(%ebp),%edx
c01029e6:	89 50 3c             	mov    %edx,0x3c(%eax)
        bool in_kernel = trap_in_kernel(tf);
c01029e9:	8b 45 08             	mov    0x8(%ebp),%eax
c01029ec:	89 04 24             	mov    %eax,(%esp)
c01029ef:	e8 a4 f9 ff ff       	call   c0102398 <trap_in_kernel>
c01029f4:	89 45 f0             	mov    %eax,-0x10(%ebp)
        trap_dispatch(tf);
c01029f7:	8b 45 08             	mov    0x8(%ebp),%eax
c01029fa:	89 04 24             	mov    %eax,(%esp)
c01029fd:	e8 65 fd ff ff       	call   c0102767 <trap_dispatch>
        current->tf = otf;
c0102a02:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c0102a07:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0102a0a:	89 50 3c             	mov    %edx,0x3c(%eax)
        if (!in_kernel) {
c0102a0d:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0102a11:	75 2c                	jne    c0102a3f <trap+0x88>
            if (current->flags & PF_EXITING) {
c0102a13:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c0102a18:	8b 40 44             	mov    0x44(%eax),%eax
c0102a1b:	83 e0 01             	and    $0x1,%eax
c0102a1e:	85 c0                	test   %eax,%eax
c0102a20:	74 0c                	je     c0102a2e <trap+0x77>
                do_exit(-E_KILLED);
c0102a22:	c7 04 24 f7 ff ff ff 	movl   $0xfffffff7,(%esp)
c0102a29:	e8 e2 75 00 00       	call   c010a010 <do_exit>
            if (current->need_resched) {
c0102a2e:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c0102a33:	8b 40 10             	mov    0x10(%eax),%eax
c0102a36:	85 c0                	test   %eax,%eax
c0102a38:	74 05                	je     c0102a3f <trap+0x88>
                schedule();
c0102a3a:	e8 3d 86 00 00       	call   c010b07c <schedule>
}
c0102a3f:	90                   	nop
c0102a40:	89 ec                	mov    %ebp,%esp
c0102a42:	5d                   	pop    %ebp
c0102a43:	c3                   	ret    

c0102a44 <__alltraps>:
.globl __alltraps
__alltraps:
    # push registers to build a trap frame
    # therefore make the stack look like a struct trapframe
    # 通过 push 指令，将数据段寄存器和所有通用寄存器（使用 pushal）的值压入栈中，以保存当前状态。
    pushl %ds
c0102a44:	1e                   	push   %ds
    pushl %es
c0102a45:	06                   	push   %es
    pushl %fs
c0102a46:	0f a0                	push   %fs
    pushl %gs
c0102a48:	0f a8                	push   %gs
    pushal
c0102a4a:	60                   	pusha  

    # load GD_KDATA into %ds and %es to set up data segments for kernel
    # 将常量 GD_KDATA 加载到 %eax 中，然后将其值复制到 %ds 和 %es 中，设置内核的数据段。
    movl $GD_KDATA, %eax
c0102a4b:	b8 10 00 00 00       	mov    $0x10,%eax
    movw %ax, %ds
c0102a50:	8e d8                	mov    %eax,%ds
    movw %ax, %es
c0102a52:	8e c0                	mov    %eax,%es

    # push %esp to pass a pointer to the trapframe as an argument to trap()
    # 将 %esp 压栈，以将指向 trapframe 的指针作为参数传递给 trap()
    pushl %esp
c0102a54:	54                   	push   %esp

    # call trap(tf), where tf=%esp
    # 调用 trap(tf)，其中 tf=%esp
    call trap
c0102a55:	e8 5d ff ff ff       	call   c01029b7 <trap>

    # pop the pushed stack pointer弹出之前压入的栈指针
    popl %esp
c0102a5a:	5c                   	pop    %esp

c0102a5b <__trapret>:
    # 返回后继续执行到 trapret...
.globl __trapret
__trapret:
    # restore registers from stack
    # 定义了返回的入口点 __trapret。
    popal
c0102a5b:	61                   	popa   

    # restore %ds, %es, %fs and %gs
    # 这里会恢复之前保存的寄存器
    popl %gs
c0102a5c:	0f a9                	pop    %gs
    popl %fs
c0102a5e:	0f a1                	pop    %fs
    popl %es
c0102a60:	07                   	pop    %es
    popl %ds
c0102a61:	1f                   	pop    %ds

    # get rid of the trap number and error code
    # 通过 iret 指令返回中断处理
    addl $0x8, %esp
c0102a62:	83 c4 08             	add    $0x8,%esp
    iret
c0102a65:	cf                   	iret   

c0102a66 <forkrets>:

.globl forkrets
forkrets:
    # set stack to this new process's trapframe
    movl 4(%esp), %esp
c0102a66:	8b 64 24 04          	mov    0x4(%esp),%esp
    jmp __trapret
c0102a6a:	eb ef                	jmp    c0102a5b <__trapret>

c0102a6c <vector0>:
# handler
.text
.globl __alltraps
.globl vector0
vector0:
  pushl $0
c0102a6c:	6a 00                	push   $0x0
  pushl $0
c0102a6e:	6a 00                	push   $0x0
  jmp __alltraps
c0102a70:	e9 cf ff ff ff       	jmp    c0102a44 <__alltraps>

c0102a75 <vector1>:
.globl vector1
vector1:
  pushl $0
c0102a75:	6a 00                	push   $0x0
  pushl $1
c0102a77:	6a 01                	push   $0x1
  jmp __alltraps
c0102a79:	e9 c6 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102a7e <vector2>:
.globl vector2
vector2:
  pushl $0
c0102a7e:	6a 00                	push   $0x0
  pushl $2
c0102a80:	6a 02                	push   $0x2
  jmp __alltraps
c0102a82:	e9 bd ff ff ff       	jmp    c0102a44 <__alltraps>

c0102a87 <vector3>:
.globl vector3
vector3:
  pushl $0
c0102a87:	6a 00                	push   $0x0
  pushl $3
c0102a89:	6a 03                	push   $0x3
  jmp __alltraps
c0102a8b:	e9 b4 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102a90 <vector4>:
.globl vector4
vector4:
  pushl $0
c0102a90:	6a 00                	push   $0x0
  pushl $4
c0102a92:	6a 04                	push   $0x4
  jmp __alltraps
c0102a94:	e9 ab ff ff ff       	jmp    c0102a44 <__alltraps>

c0102a99 <vector5>:
.globl vector5
vector5:
  pushl $0
c0102a99:	6a 00                	push   $0x0
  pushl $5
c0102a9b:	6a 05                	push   $0x5
  jmp __alltraps
c0102a9d:	e9 a2 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102aa2 <vector6>:
.globl vector6
vector6:
  pushl $0
c0102aa2:	6a 00                	push   $0x0
  pushl $6
c0102aa4:	6a 06                	push   $0x6
  jmp __alltraps
c0102aa6:	e9 99 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102aab <vector7>:
.globl vector7
vector7:
  pushl $0
c0102aab:	6a 00                	push   $0x0
  pushl $7
c0102aad:	6a 07                	push   $0x7
  jmp __alltraps
c0102aaf:	e9 90 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102ab4 <vector8>:
.globl vector8
vector8:
  pushl $8
c0102ab4:	6a 08                	push   $0x8
  jmp __alltraps
c0102ab6:	e9 89 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102abb <vector9>:
.globl vector9
vector9:
  pushl $0
c0102abb:	6a 00                	push   $0x0
  pushl $9
c0102abd:	6a 09                	push   $0x9
  jmp __alltraps
c0102abf:	e9 80 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102ac4 <vector10>:
.globl vector10
vector10:
  pushl $10
c0102ac4:	6a 0a                	push   $0xa
  jmp __alltraps
c0102ac6:	e9 79 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102acb <vector11>:
.globl vector11
vector11:
  pushl $11
c0102acb:	6a 0b                	push   $0xb
  jmp __alltraps
c0102acd:	e9 72 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102ad2 <vector12>:
.globl vector12
vector12:
  pushl $12
c0102ad2:	6a 0c                	push   $0xc
  jmp __alltraps
c0102ad4:	e9 6b ff ff ff       	jmp    c0102a44 <__alltraps>

c0102ad9 <vector13>:
.globl vector13
vector13:
  pushl $13
c0102ad9:	6a 0d                	push   $0xd
  jmp __alltraps
c0102adb:	e9 64 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102ae0 <vector14>:
.globl vector14
vector14:
  pushl $14
c0102ae0:	6a 0e                	push   $0xe
  jmp __alltraps
c0102ae2:	e9 5d ff ff ff       	jmp    c0102a44 <__alltraps>

c0102ae7 <vector15>:
.globl vector15
vector15:
  pushl $0
c0102ae7:	6a 00                	push   $0x0
  pushl $15
c0102ae9:	6a 0f                	push   $0xf
  jmp __alltraps
c0102aeb:	e9 54 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102af0 <vector16>:
.globl vector16
vector16:
  pushl $0
c0102af0:	6a 00                	push   $0x0
  pushl $16
c0102af2:	6a 10                	push   $0x10
  jmp __alltraps
c0102af4:	e9 4b ff ff ff       	jmp    c0102a44 <__alltraps>

c0102af9 <vector17>:
.globl vector17
vector17:
  pushl $17
c0102af9:	6a 11                	push   $0x11
  jmp __alltraps
c0102afb:	e9 44 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102b00 <vector18>:
.globl vector18
vector18:
  pushl $0
c0102b00:	6a 00                	push   $0x0
  pushl $18
c0102b02:	6a 12                	push   $0x12
  jmp __alltraps
c0102b04:	e9 3b ff ff ff       	jmp    c0102a44 <__alltraps>

c0102b09 <vector19>:
.globl vector19
vector19:
  pushl $0
c0102b09:	6a 00                	push   $0x0
  pushl $19
c0102b0b:	6a 13                	push   $0x13
  jmp __alltraps
c0102b0d:	e9 32 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102b12 <vector20>:
.globl vector20
vector20:
  pushl $0
c0102b12:	6a 00                	push   $0x0
  pushl $20
c0102b14:	6a 14                	push   $0x14
  jmp __alltraps
c0102b16:	e9 29 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102b1b <vector21>:
.globl vector21
vector21:
  pushl $0
c0102b1b:	6a 00                	push   $0x0
  pushl $21
c0102b1d:	6a 15                	push   $0x15
  jmp __alltraps
c0102b1f:	e9 20 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102b24 <vector22>:
.globl vector22
vector22:
  pushl $0
c0102b24:	6a 00                	push   $0x0
  pushl $22
c0102b26:	6a 16                	push   $0x16
  jmp __alltraps
c0102b28:	e9 17 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102b2d <vector23>:
.globl vector23
vector23:
  pushl $0
c0102b2d:	6a 00                	push   $0x0
  pushl $23
c0102b2f:	6a 17                	push   $0x17
  jmp __alltraps
c0102b31:	e9 0e ff ff ff       	jmp    c0102a44 <__alltraps>

c0102b36 <vector24>:
.globl vector24
vector24:
  pushl $0
c0102b36:	6a 00                	push   $0x0
  pushl $24
c0102b38:	6a 18                	push   $0x18
  jmp __alltraps
c0102b3a:	e9 05 ff ff ff       	jmp    c0102a44 <__alltraps>

c0102b3f <vector25>:
.globl vector25
vector25:
  pushl $0
c0102b3f:	6a 00                	push   $0x0
  pushl $25
c0102b41:	6a 19                	push   $0x19
  jmp __alltraps
c0102b43:	e9 fc fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b48 <vector26>:
.globl vector26
vector26:
  pushl $0
c0102b48:	6a 00                	push   $0x0
  pushl $26
c0102b4a:	6a 1a                	push   $0x1a
  jmp __alltraps
c0102b4c:	e9 f3 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b51 <vector27>:
.globl vector27
vector27:
  pushl $0
c0102b51:	6a 00                	push   $0x0
  pushl $27
c0102b53:	6a 1b                	push   $0x1b
  jmp __alltraps
c0102b55:	e9 ea fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b5a <vector28>:
.globl vector28
vector28:
  pushl $0
c0102b5a:	6a 00                	push   $0x0
  pushl $28
c0102b5c:	6a 1c                	push   $0x1c
  jmp __alltraps
c0102b5e:	e9 e1 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b63 <vector29>:
.globl vector29
vector29:
  pushl $0
c0102b63:	6a 00                	push   $0x0
  pushl $29
c0102b65:	6a 1d                	push   $0x1d
  jmp __alltraps
c0102b67:	e9 d8 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b6c <vector30>:
.globl vector30
vector30:
  pushl $0
c0102b6c:	6a 00                	push   $0x0
  pushl $30
c0102b6e:	6a 1e                	push   $0x1e
  jmp __alltraps
c0102b70:	e9 cf fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b75 <vector31>:
.globl vector31
vector31:
  pushl $0
c0102b75:	6a 00                	push   $0x0
  pushl $31
c0102b77:	6a 1f                	push   $0x1f
  jmp __alltraps
c0102b79:	e9 c6 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b7e <vector32>:
.globl vector32
vector32:
  pushl $0
c0102b7e:	6a 00                	push   $0x0
  pushl $32
c0102b80:	6a 20                	push   $0x20
  jmp __alltraps
c0102b82:	e9 bd fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b87 <vector33>:
.globl vector33
vector33:
  pushl $0
c0102b87:	6a 00                	push   $0x0
  pushl $33
c0102b89:	6a 21                	push   $0x21
  jmp __alltraps
c0102b8b:	e9 b4 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b90 <vector34>:
.globl vector34
vector34:
  pushl $0
c0102b90:	6a 00                	push   $0x0
  pushl $34
c0102b92:	6a 22                	push   $0x22
  jmp __alltraps
c0102b94:	e9 ab fe ff ff       	jmp    c0102a44 <__alltraps>

c0102b99 <vector35>:
.globl vector35
vector35:
  pushl $0
c0102b99:	6a 00                	push   $0x0
  pushl $35
c0102b9b:	6a 23                	push   $0x23
  jmp __alltraps
c0102b9d:	e9 a2 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102ba2 <vector36>:
.globl vector36
vector36:
  pushl $0
c0102ba2:	6a 00                	push   $0x0
  pushl $36
c0102ba4:	6a 24                	push   $0x24
  jmp __alltraps
c0102ba6:	e9 99 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bab <vector37>:
.globl vector37
vector37:
  pushl $0
c0102bab:	6a 00                	push   $0x0
  pushl $37
c0102bad:	6a 25                	push   $0x25
  jmp __alltraps
c0102baf:	e9 90 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bb4 <vector38>:
.globl vector38
vector38:
  pushl $0
c0102bb4:	6a 00                	push   $0x0
  pushl $38
c0102bb6:	6a 26                	push   $0x26
  jmp __alltraps
c0102bb8:	e9 87 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bbd <vector39>:
.globl vector39
vector39:
  pushl $0
c0102bbd:	6a 00                	push   $0x0
  pushl $39
c0102bbf:	6a 27                	push   $0x27
  jmp __alltraps
c0102bc1:	e9 7e fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bc6 <vector40>:
.globl vector40
vector40:
  pushl $0
c0102bc6:	6a 00                	push   $0x0
  pushl $40
c0102bc8:	6a 28                	push   $0x28
  jmp __alltraps
c0102bca:	e9 75 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bcf <vector41>:
.globl vector41
vector41:
  pushl $0
c0102bcf:	6a 00                	push   $0x0
  pushl $41
c0102bd1:	6a 29                	push   $0x29
  jmp __alltraps
c0102bd3:	e9 6c fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bd8 <vector42>:
.globl vector42
vector42:
  pushl $0
c0102bd8:	6a 00                	push   $0x0
  pushl $42
c0102bda:	6a 2a                	push   $0x2a
  jmp __alltraps
c0102bdc:	e9 63 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102be1 <vector43>:
.globl vector43
vector43:
  pushl $0
c0102be1:	6a 00                	push   $0x0
  pushl $43
c0102be3:	6a 2b                	push   $0x2b
  jmp __alltraps
c0102be5:	e9 5a fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bea <vector44>:
.globl vector44
vector44:
  pushl $0
c0102bea:	6a 00                	push   $0x0
  pushl $44
c0102bec:	6a 2c                	push   $0x2c
  jmp __alltraps
c0102bee:	e9 51 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bf3 <vector45>:
.globl vector45
vector45:
  pushl $0
c0102bf3:	6a 00                	push   $0x0
  pushl $45
c0102bf5:	6a 2d                	push   $0x2d
  jmp __alltraps
c0102bf7:	e9 48 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102bfc <vector46>:
.globl vector46
vector46:
  pushl $0
c0102bfc:	6a 00                	push   $0x0
  pushl $46
c0102bfe:	6a 2e                	push   $0x2e
  jmp __alltraps
c0102c00:	e9 3f fe ff ff       	jmp    c0102a44 <__alltraps>

c0102c05 <vector47>:
.globl vector47
vector47:
  pushl $0
c0102c05:	6a 00                	push   $0x0
  pushl $47
c0102c07:	6a 2f                	push   $0x2f
  jmp __alltraps
c0102c09:	e9 36 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102c0e <vector48>:
.globl vector48
vector48:
  pushl $0
c0102c0e:	6a 00                	push   $0x0
  pushl $48
c0102c10:	6a 30                	push   $0x30
  jmp __alltraps
c0102c12:	e9 2d fe ff ff       	jmp    c0102a44 <__alltraps>

c0102c17 <vector49>:
.globl vector49
vector49:
  pushl $0
c0102c17:	6a 00                	push   $0x0
  pushl $49
c0102c19:	6a 31                	push   $0x31
  jmp __alltraps
c0102c1b:	e9 24 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102c20 <vector50>:
.globl vector50
vector50:
  pushl $0
c0102c20:	6a 00                	push   $0x0
  pushl $50
c0102c22:	6a 32                	push   $0x32
  jmp __alltraps
c0102c24:	e9 1b fe ff ff       	jmp    c0102a44 <__alltraps>

c0102c29 <vector51>:
.globl vector51
vector51:
  pushl $0
c0102c29:	6a 00                	push   $0x0
  pushl $51
c0102c2b:	6a 33                	push   $0x33
  jmp __alltraps
c0102c2d:	e9 12 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102c32 <vector52>:
.globl vector52
vector52:
  pushl $0
c0102c32:	6a 00                	push   $0x0
  pushl $52
c0102c34:	6a 34                	push   $0x34
  jmp __alltraps
c0102c36:	e9 09 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102c3b <vector53>:
.globl vector53
vector53:
  pushl $0
c0102c3b:	6a 00                	push   $0x0
  pushl $53
c0102c3d:	6a 35                	push   $0x35
  jmp __alltraps
c0102c3f:	e9 00 fe ff ff       	jmp    c0102a44 <__alltraps>

c0102c44 <vector54>:
.globl vector54
vector54:
  pushl $0
c0102c44:	6a 00                	push   $0x0
  pushl $54
c0102c46:	6a 36                	push   $0x36
  jmp __alltraps
c0102c48:	e9 f7 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c4d <vector55>:
.globl vector55
vector55:
  pushl $0
c0102c4d:	6a 00                	push   $0x0
  pushl $55
c0102c4f:	6a 37                	push   $0x37
  jmp __alltraps
c0102c51:	e9 ee fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c56 <vector56>:
.globl vector56
vector56:
  pushl $0
c0102c56:	6a 00                	push   $0x0
  pushl $56
c0102c58:	6a 38                	push   $0x38
  jmp __alltraps
c0102c5a:	e9 e5 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c5f <vector57>:
.globl vector57
vector57:
  pushl $0
c0102c5f:	6a 00                	push   $0x0
  pushl $57
c0102c61:	6a 39                	push   $0x39
  jmp __alltraps
c0102c63:	e9 dc fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c68 <vector58>:
.globl vector58
vector58:
  pushl $0
c0102c68:	6a 00                	push   $0x0
  pushl $58
c0102c6a:	6a 3a                	push   $0x3a
  jmp __alltraps
c0102c6c:	e9 d3 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c71 <vector59>:
.globl vector59
vector59:
  pushl $0
c0102c71:	6a 00                	push   $0x0
  pushl $59
c0102c73:	6a 3b                	push   $0x3b
  jmp __alltraps
c0102c75:	e9 ca fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c7a <vector60>:
.globl vector60
vector60:
  pushl $0
c0102c7a:	6a 00                	push   $0x0
  pushl $60
c0102c7c:	6a 3c                	push   $0x3c
  jmp __alltraps
c0102c7e:	e9 c1 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c83 <vector61>:
.globl vector61
vector61:
  pushl $0
c0102c83:	6a 00                	push   $0x0
  pushl $61
c0102c85:	6a 3d                	push   $0x3d
  jmp __alltraps
c0102c87:	e9 b8 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c8c <vector62>:
.globl vector62
vector62:
  pushl $0
c0102c8c:	6a 00                	push   $0x0
  pushl $62
c0102c8e:	6a 3e                	push   $0x3e
  jmp __alltraps
c0102c90:	e9 af fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c95 <vector63>:
.globl vector63
vector63:
  pushl $0
c0102c95:	6a 00                	push   $0x0
  pushl $63
c0102c97:	6a 3f                	push   $0x3f
  jmp __alltraps
c0102c99:	e9 a6 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102c9e <vector64>:
.globl vector64
vector64:
  pushl $0
c0102c9e:	6a 00                	push   $0x0
  pushl $64
c0102ca0:	6a 40                	push   $0x40
  jmp __alltraps
c0102ca2:	e9 9d fd ff ff       	jmp    c0102a44 <__alltraps>

c0102ca7 <vector65>:
.globl vector65
vector65:
  pushl $0
c0102ca7:	6a 00                	push   $0x0
  pushl $65
c0102ca9:	6a 41                	push   $0x41
  jmp __alltraps
c0102cab:	e9 94 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102cb0 <vector66>:
.globl vector66
vector66:
  pushl $0
c0102cb0:	6a 00                	push   $0x0
  pushl $66
c0102cb2:	6a 42                	push   $0x42
  jmp __alltraps
c0102cb4:	e9 8b fd ff ff       	jmp    c0102a44 <__alltraps>

c0102cb9 <vector67>:
.globl vector67
vector67:
  pushl $0
c0102cb9:	6a 00                	push   $0x0
  pushl $67
c0102cbb:	6a 43                	push   $0x43
  jmp __alltraps
c0102cbd:	e9 82 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102cc2 <vector68>:
.globl vector68
vector68:
  pushl $0
c0102cc2:	6a 00                	push   $0x0
  pushl $68
c0102cc4:	6a 44                	push   $0x44
  jmp __alltraps
c0102cc6:	e9 79 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102ccb <vector69>:
.globl vector69
vector69:
  pushl $0
c0102ccb:	6a 00                	push   $0x0
  pushl $69
c0102ccd:	6a 45                	push   $0x45
  jmp __alltraps
c0102ccf:	e9 70 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102cd4 <vector70>:
.globl vector70
vector70:
  pushl $0
c0102cd4:	6a 00                	push   $0x0
  pushl $70
c0102cd6:	6a 46                	push   $0x46
  jmp __alltraps
c0102cd8:	e9 67 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102cdd <vector71>:
.globl vector71
vector71:
  pushl $0
c0102cdd:	6a 00                	push   $0x0
  pushl $71
c0102cdf:	6a 47                	push   $0x47
  jmp __alltraps
c0102ce1:	e9 5e fd ff ff       	jmp    c0102a44 <__alltraps>

c0102ce6 <vector72>:
.globl vector72
vector72:
  pushl $0
c0102ce6:	6a 00                	push   $0x0
  pushl $72
c0102ce8:	6a 48                	push   $0x48
  jmp __alltraps
c0102cea:	e9 55 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102cef <vector73>:
.globl vector73
vector73:
  pushl $0
c0102cef:	6a 00                	push   $0x0
  pushl $73
c0102cf1:	6a 49                	push   $0x49
  jmp __alltraps
c0102cf3:	e9 4c fd ff ff       	jmp    c0102a44 <__alltraps>

c0102cf8 <vector74>:
.globl vector74
vector74:
  pushl $0
c0102cf8:	6a 00                	push   $0x0
  pushl $74
c0102cfa:	6a 4a                	push   $0x4a
  jmp __alltraps
c0102cfc:	e9 43 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102d01 <vector75>:
.globl vector75
vector75:
  pushl $0
c0102d01:	6a 00                	push   $0x0
  pushl $75
c0102d03:	6a 4b                	push   $0x4b
  jmp __alltraps
c0102d05:	e9 3a fd ff ff       	jmp    c0102a44 <__alltraps>

c0102d0a <vector76>:
.globl vector76
vector76:
  pushl $0
c0102d0a:	6a 00                	push   $0x0
  pushl $76
c0102d0c:	6a 4c                	push   $0x4c
  jmp __alltraps
c0102d0e:	e9 31 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102d13 <vector77>:
.globl vector77
vector77:
  pushl $0
c0102d13:	6a 00                	push   $0x0
  pushl $77
c0102d15:	6a 4d                	push   $0x4d
  jmp __alltraps
c0102d17:	e9 28 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102d1c <vector78>:
.globl vector78
vector78:
  pushl $0
c0102d1c:	6a 00                	push   $0x0
  pushl $78
c0102d1e:	6a 4e                	push   $0x4e
  jmp __alltraps
c0102d20:	e9 1f fd ff ff       	jmp    c0102a44 <__alltraps>

c0102d25 <vector79>:
.globl vector79
vector79:
  pushl $0
c0102d25:	6a 00                	push   $0x0
  pushl $79
c0102d27:	6a 4f                	push   $0x4f
  jmp __alltraps
c0102d29:	e9 16 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102d2e <vector80>:
.globl vector80
vector80:
  pushl $0
c0102d2e:	6a 00                	push   $0x0
  pushl $80
c0102d30:	6a 50                	push   $0x50
  jmp __alltraps
c0102d32:	e9 0d fd ff ff       	jmp    c0102a44 <__alltraps>

c0102d37 <vector81>:
.globl vector81
vector81:
  pushl $0
c0102d37:	6a 00                	push   $0x0
  pushl $81
c0102d39:	6a 51                	push   $0x51
  jmp __alltraps
c0102d3b:	e9 04 fd ff ff       	jmp    c0102a44 <__alltraps>

c0102d40 <vector82>:
.globl vector82
vector82:
  pushl $0
c0102d40:	6a 00                	push   $0x0
  pushl $82
c0102d42:	6a 52                	push   $0x52
  jmp __alltraps
c0102d44:	e9 fb fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d49 <vector83>:
.globl vector83
vector83:
  pushl $0
c0102d49:	6a 00                	push   $0x0
  pushl $83
c0102d4b:	6a 53                	push   $0x53
  jmp __alltraps
c0102d4d:	e9 f2 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d52 <vector84>:
.globl vector84
vector84:
  pushl $0
c0102d52:	6a 00                	push   $0x0
  pushl $84
c0102d54:	6a 54                	push   $0x54
  jmp __alltraps
c0102d56:	e9 e9 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d5b <vector85>:
.globl vector85
vector85:
  pushl $0
c0102d5b:	6a 00                	push   $0x0
  pushl $85
c0102d5d:	6a 55                	push   $0x55
  jmp __alltraps
c0102d5f:	e9 e0 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d64 <vector86>:
.globl vector86
vector86:
  pushl $0
c0102d64:	6a 00                	push   $0x0
  pushl $86
c0102d66:	6a 56                	push   $0x56
  jmp __alltraps
c0102d68:	e9 d7 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d6d <vector87>:
.globl vector87
vector87:
  pushl $0
c0102d6d:	6a 00                	push   $0x0
  pushl $87
c0102d6f:	6a 57                	push   $0x57
  jmp __alltraps
c0102d71:	e9 ce fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d76 <vector88>:
.globl vector88
vector88:
  pushl $0
c0102d76:	6a 00                	push   $0x0
  pushl $88
c0102d78:	6a 58                	push   $0x58
  jmp __alltraps
c0102d7a:	e9 c5 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d7f <vector89>:
.globl vector89
vector89:
  pushl $0
c0102d7f:	6a 00                	push   $0x0
  pushl $89
c0102d81:	6a 59                	push   $0x59
  jmp __alltraps
c0102d83:	e9 bc fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d88 <vector90>:
.globl vector90
vector90:
  pushl $0
c0102d88:	6a 00                	push   $0x0
  pushl $90
c0102d8a:	6a 5a                	push   $0x5a
  jmp __alltraps
c0102d8c:	e9 b3 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d91 <vector91>:
.globl vector91
vector91:
  pushl $0
c0102d91:	6a 00                	push   $0x0
  pushl $91
c0102d93:	6a 5b                	push   $0x5b
  jmp __alltraps
c0102d95:	e9 aa fc ff ff       	jmp    c0102a44 <__alltraps>

c0102d9a <vector92>:
.globl vector92
vector92:
  pushl $0
c0102d9a:	6a 00                	push   $0x0
  pushl $92
c0102d9c:	6a 5c                	push   $0x5c
  jmp __alltraps
c0102d9e:	e9 a1 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102da3 <vector93>:
.globl vector93
vector93:
  pushl $0
c0102da3:	6a 00                	push   $0x0
  pushl $93
c0102da5:	6a 5d                	push   $0x5d
  jmp __alltraps
c0102da7:	e9 98 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102dac <vector94>:
.globl vector94
vector94:
  pushl $0
c0102dac:	6a 00                	push   $0x0
  pushl $94
c0102dae:	6a 5e                	push   $0x5e
  jmp __alltraps
c0102db0:	e9 8f fc ff ff       	jmp    c0102a44 <__alltraps>

c0102db5 <vector95>:
.globl vector95
vector95:
  pushl $0
c0102db5:	6a 00                	push   $0x0
  pushl $95
c0102db7:	6a 5f                	push   $0x5f
  jmp __alltraps
c0102db9:	e9 86 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102dbe <vector96>:
.globl vector96
vector96:
  pushl $0
c0102dbe:	6a 00                	push   $0x0
  pushl $96
c0102dc0:	6a 60                	push   $0x60
  jmp __alltraps
c0102dc2:	e9 7d fc ff ff       	jmp    c0102a44 <__alltraps>

c0102dc7 <vector97>:
.globl vector97
vector97:
  pushl $0
c0102dc7:	6a 00                	push   $0x0
  pushl $97
c0102dc9:	6a 61                	push   $0x61
  jmp __alltraps
c0102dcb:	e9 74 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102dd0 <vector98>:
.globl vector98
vector98:
  pushl $0
c0102dd0:	6a 00                	push   $0x0
  pushl $98
c0102dd2:	6a 62                	push   $0x62
  jmp __alltraps
c0102dd4:	e9 6b fc ff ff       	jmp    c0102a44 <__alltraps>

c0102dd9 <vector99>:
.globl vector99
vector99:
  pushl $0
c0102dd9:	6a 00                	push   $0x0
  pushl $99
c0102ddb:	6a 63                	push   $0x63
  jmp __alltraps
c0102ddd:	e9 62 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102de2 <vector100>:
.globl vector100
vector100:
  pushl $0
c0102de2:	6a 00                	push   $0x0
  pushl $100
c0102de4:	6a 64                	push   $0x64
  jmp __alltraps
c0102de6:	e9 59 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102deb <vector101>:
.globl vector101
vector101:
  pushl $0
c0102deb:	6a 00                	push   $0x0
  pushl $101
c0102ded:	6a 65                	push   $0x65
  jmp __alltraps
c0102def:	e9 50 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102df4 <vector102>:
.globl vector102
vector102:
  pushl $0
c0102df4:	6a 00                	push   $0x0
  pushl $102
c0102df6:	6a 66                	push   $0x66
  jmp __alltraps
c0102df8:	e9 47 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102dfd <vector103>:
.globl vector103
vector103:
  pushl $0
c0102dfd:	6a 00                	push   $0x0
  pushl $103
c0102dff:	6a 67                	push   $0x67
  jmp __alltraps
c0102e01:	e9 3e fc ff ff       	jmp    c0102a44 <__alltraps>

c0102e06 <vector104>:
.globl vector104
vector104:
  pushl $0
c0102e06:	6a 00                	push   $0x0
  pushl $104
c0102e08:	6a 68                	push   $0x68
  jmp __alltraps
c0102e0a:	e9 35 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102e0f <vector105>:
.globl vector105
vector105:
  pushl $0
c0102e0f:	6a 00                	push   $0x0
  pushl $105
c0102e11:	6a 69                	push   $0x69
  jmp __alltraps
c0102e13:	e9 2c fc ff ff       	jmp    c0102a44 <__alltraps>

c0102e18 <vector106>:
.globl vector106
vector106:
  pushl $0
c0102e18:	6a 00                	push   $0x0
  pushl $106
c0102e1a:	6a 6a                	push   $0x6a
  jmp __alltraps
c0102e1c:	e9 23 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102e21 <vector107>:
.globl vector107
vector107:
  pushl $0
c0102e21:	6a 00                	push   $0x0
  pushl $107
c0102e23:	6a 6b                	push   $0x6b
  jmp __alltraps
c0102e25:	e9 1a fc ff ff       	jmp    c0102a44 <__alltraps>

c0102e2a <vector108>:
.globl vector108
vector108:
  pushl $0
c0102e2a:	6a 00                	push   $0x0
  pushl $108
c0102e2c:	6a 6c                	push   $0x6c
  jmp __alltraps
c0102e2e:	e9 11 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102e33 <vector109>:
.globl vector109
vector109:
  pushl $0
c0102e33:	6a 00                	push   $0x0
  pushl $109
c0102e35:	6a 6d                	push   $0x6d
  jmp __alltraps
c0102e37:	e9 08 fc ff ff       	jmp    c0102a44 <__alltraps>

c0102e3c <vector110>:
.globl vector110
vector110:
  pushl $0
c0102e3c:	6a 00                	push   $0x0
  pushl $110
c0102e3e:	6a 6e                	push   $0x6e
  jmp __alltraps
c0102e40:	e9 ff fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e45 <vector111>:
.globl vector111
vector111:
  pushl $0
c0102e45:	6a 00                	push   $0x0
  pushl $111
c0102e47:	6a 6f                	push   $0x6f
  jmp __alltraps
c0102e49:	e9 f6 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e4e <vector112>:
.globl vector112
vector112:
  pushl $0
c0102e4e:	6a 00                	push   $0x0
  pushl $112
c0102e50:	6a 70                	push   $0x70
  jmp __alltraps
c0102e52:	e9 ed fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e57 <vector113>:
.globl vector113
vector113:
  pushl $0
c0102e57:	6a 00                	push   $0x0
  pushl $113
c0102e59:	6a 71                	push   $0x71
  jmp __alltraps
c0102e5b:	e9 e4 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e60 <vector114>:
.globl vector114
vector114:
  pushl $0
c0102e60:	6a 00                	push   $0x0
  pushl $114
c0102e62:	6a 72                	push   $0x72
  jmp __alltraps
c0102e64:	e9 db fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e69 <vector115>:
.globl vector115
vector115:
  pushl $0
c0102e69:	6a 00                	push   $0x0
  pushl $115
c0102e6b:	6a 73                	push   $0x73
  jmp __alltraps
c0102e6d:	e9 d2 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e72 <vector116>:
.globl vector116
vector116:
  pushl $0
c0102e72:	6a 00                	push   $0x0
  pushl $116
c0102e74:	6a 74                	push   $0x74
  jmp __alltraps
c0102e76:	e9 c9 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e7b <vector117>:
.globl vector117
vector117:
  pushl $0
c0102e7b:	6a 00                	push   $0x0
  pushl $117
c0102e7d:	6a 75                	push   $0x75
  jmp __alltraps
c0102e7f:	e9 c0 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e84 <vector118>:
.globl vector118
vector118:
  pushl $0
c0102e84:	6a 00                	push   $0x0
  pushl $118
c0102e86:	6a 76                	push   $0x76
  jmp __alltraps
c0102e88:	e9 b7 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e8d <vector119>:
.globl vector119
vector119:
  pushl $0
c0102e8d:	6a 00                	push   $0x0
  pushl $119
c0102e8f:	6a 77                	push   $0x77
  jmp __alltraps
c0102e91:	e9 ae fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e96 <vector120>:
.globl vector120
vector120:
  pushl $0
c0102e96:	6a 00                	push   $0x0
  pushl $120
c0102e98:	6a 78                	push   $0x78
  jmp __alltraps
c0102e9a:	e9 a5 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102e9f <vector121>:
.globl vector121
vector121:
  pushl $0
c0102e9f:	6a 00                	push   $0x0
  pushl $121
c0102ea1:	6a 79                	push   $0x79
  jmp __alltraps
c0102ea3:	e9 9c fb ff ff       	jmp    c0102a44 <__alltraps>

c0102ea8 <vector122>:
.globl vector122
vector122:
  pushl $0
c0102ea8:	6a 00                	push   $0x0
  pushl $122
c0102eaa:	6a 7a                	push   $0x7a
  jmp __alltraps
c0102eac:	e9 93 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102eb1 <vector123>:
.globl vector123
vector123:
  pushl $0
c0102eb1:	6a 00                	push   $0x0
  pushl $123
c0102eb3:	6a 7b                	push   $0x7b
  jmp __alltraps
c0102eb5:	e9 8a fb ff ff       	jmp    c0102a44 <__alltraps>

c0102eba <vector124>:
.globl vector124
vector124:
  pushl $0
c0102eba:	6a 00                	push   $0x0
  pushl $124
c0102ebc:	6a 7c                	push   $0x7c
  jmp __alltraps
c0102ebe:	e9 81 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102ec3 <vector125>:
.globl vector125
vector125:
  pushl $0
c0102ec3:	6a 00                	push   $0x0
  pushl $125
c0102ec5:	6a 7d                	push   $0x7d
  jmp __alltraps
c0102ec7:	e9 78 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102ecc <vector126>:
.globl vector126
vector126:
  pushl $0
c0102ecc:	6a 00                	push   $0x0
  pushl $126
c0102ece:	6a 7e                	push   $0x7e
  jmp __alltraps
c0102ed0:	e9 6f fb ff ff       	jmp    c0102a44 <__alltraps>

c0102ed5 <vector127>:
.globl vector127
vector127:
  pushl $0
c0102ed5:	6a 00                	push   $0x0
  pushl $127
c0102ed7:	6a 7f                	push   $0x7f
  jmp __alltraps
c0102ed9:	e9 66 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102ede <vector128>:
.globl vector128
vector128:
  pushl $0
c0102ede:	6a 00                	push   $0x0
  pushl $128
c0102ee0:	68 80 00 00 00       	push   $0x80
  jmp __alltraps
c0102ee5:	e9 5a fb ff ff       	jmp    c0102a44 <__alltraps>

c0102eea <vector129>:
.globl vector129
vector129:
  pushl $0
c0102eea:	6a 00                	push   $0x0
  pushl $129
c0102eec:	68 81 00 00 00       	push   $0x81
  jmp __alltraps
c0102ef1:	e9 4e fb ff ff       	jmp    c0102a44 <__alltraps>

c0102ef6 <vector130>:
.globl vector130
vector130:
  pushl $0
c0102ef6:	6a 00                	push   $0x0
  pushl $130
c0102ef8:	68 82 00 00 00       	push   $0x82
  jmp __alltraps
c0102efd:	e9 42 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102f02 <vector131>:
.globl vector131
vector131:
  pushl $0
c0102f02:	6a 00                	push   $0x0
  pushl $131
c0102f04:	68 83 00 00 00       	push   $0x83
  jmp __alltraps
c0102f09:	e9 36 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102f0e <vector132>:
.globl vector132
vector132:
  pushl $0
c0102f0e:	6a 00                	push   $0x0
  pushl $132
c0102f10:	68 84 00 00 00       	push   $0x84
  jmp __alltraps
c0102f15:	e9 2a fb ff ff       	jmp    c0102a44 <__alltraps>

c0102f1a <vector133>:
.globl vector133
vector133:
  pushl $0
c0102f1a:	6a 00                	push   $0x0
  pushl $133
c0102f1c:	68 85 00 00 00       	push   $0x85
  jmp __alltraps
c0102f21:	e9 1e fb ff ff       	jmp    c0102a44 <__alltraps>

c0102f26 <vector134>:
.globl vector134
vector134:
  pushl $0
c0102f26:	6a 00                	push   $0x0
  pushl $134
c0102f28:	68 86 00 00 00       	push   $0x86
  jmp __alltraps
c0102f2d:	e9 12 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102f32 <vector135>:
.globl vector135
vector135:
  pushl $0
c0102f32:	6a 00                	push   $0x0
  pushl $135
c0102f34:	68 87 00 00 00       	push   $0x87
  jmp __alltraps
c0102f39:	e9 06 fb ff ff       	jmp    c0102a44 <__alltraps>

c0102f3e <vector136>:
.globl vector136
vector136:
  pushl $0
c0102f3e:	6a 00                	push   $0x0
  pushl $136
c0102f40:	68 88 00 00 00       	push   $0x88
  jmp __alltraps
c0102f45:	e9 fa fa ff ff       	jmp    c0102a44 <__alltraps>

c0102f4a <vector137>:
.globl vector137
vector137:
  pushl $0
c0102f4a:	6a 00                	push   $0x0
  pushl $137
c0102f4c:	68 89 00 00 00       	push   $0x89
  jmp __alltraps
c0102f51:	e9 ee fa ff ff       	jmp    c0102a44 <__alltraps>

c0102f56 <vector138>:
.globl vector138
vector138:
  pushl $0
c0102f56:	6a 00                	push   $0x0
  pushl $138
c0102f58:	68 8a 00 00 00       	push   $0x8a
  jmp __alltraps
c0102f5d:	e9 e2 fa ff ff       	jmp    c0102a44 <__alltraps>

c0102f62 <vector139>:
.globl vector139
vector139:
  pushl $0
c0102f62:	6a 00                	push   $0x0
  pushl $139
c0102f64:	68 8b 00 00 00       	push   $0x8b
  jmp __alltraps
c0102f69:	e9 d6 fa ff ff       	jmp    c0102a44 <__alltraps>

c0102f6e <vector140>:
.globl vector140
vector140:
  pushl $0
c0102f6e:	6a 00                	push   $0x0
  pushl $140
c0102f70:	68 8c 00 00 00       	push   $0x8c
  jmp __alltraps
c0102f75:	e9 ca fa ff ff       	jmp    c0102a44 <__alltraps>

c0102f7a <vector141>:
.globl vector141
vector141:
  pushl $0
c0102f7a:	6a 00                	push   $0x0
  pushl $141
c0102f7c:	68 8d 00 00 00       	push   $0x8d
  jmp __alltraps
c0102f81:	e9 be fa ff ff       	jmp    c0102a44 <__alltraps>

c0102f86 <vector142>:
.globl vector142
vector142:
  pushl $0
c0102f86:	6a 00                	push   $0x0
  pushl $142
c0102f88:	68 8e 00 00 00       	push   $0x8e
  jmp __alltraps
c0102f8d:	e9 b2 fa ff ff       	jmp    c0102a44 <__alltraps>

c0102f92 <vector143>:
.globl vector143
vector143:
  pushl $0
c0102f92:	6a 00                	push   $0x0
  pushl $143
c0102f94:	68 8f 00 00 00       	push   $0x8f
  jmp __alltraps
c0102f99:	e9 a6 fa ff ff       	jmp    c0102a44 <__alltraps>

c0102f9e <vector144>:
.globl vector144
vector144:
  pushl $0
c0102f9e:	6a 00                	push   $0x0
  pushl $144
c0102fa0:	68 90 00 00 00       	push   $0x90
  jmp __alltraps
c0102fa5:	e9 9a fa ff ff       	jmp    c0102a44 <__alltraps>

c0102faa <vector145>:
.globl vector145
vector145:
  pushl $0
c0102faa:	6a 00                	push   $0x0
  pushl $145
c0102fac:	68 91 00 00 00       	push   $0x91
  jmp __alltraps
c0102fb1:	e9 8e fa ff ff       	jmp    c0102a44 <__alltraps>

c0102fb6 <vector146>:
.globl vector146
vector146:
  pushl $0
c0102fb6:	6a 00                	push   $0x0
  pushl $146
c0102fb8:	68 92 00 00 00       	push   $0x92
  jmp __alltraps
c0102fbd:	e9 82 fa ff ff       	jmp    c0102a44 <__alltraps>

c0102fc2 <vector147>:
.globl vector147
vector147:
  pushl $0
c0102fc2:	6a 00                	push   $0x0
  pushl $147
c0102fc4:	68 93 00 00 00       	push   $0x93
  jmp __alltraps
c0102fc9:	e9 76 fa ff ff       	jmp    c0102a44 <__alltraps>

c0102fce <vector148>:
.globl vector148
vector148:
  pushl $0
c0102fce:	6a 00                	push   $0x0
  pushl $148
c0102fd0:	68 94 00 00 00       	push   $0x94
  jmp __alltraps
c0102fd5:	e9 6a fa ff ff       	jmp    c0102a44 <__alltraps>

c0102fda <vector149>:
.globl vector149
vector149:
  pushl $0
c0102fda:	6a 00                	push   $0x0
  pushl $149
c0102fdc:	68 95 00 00 00       	push   $0x95
  jmp __alltraps
c0102fe1:	e9 5e fa ff ff       	jmp    c0102a44 <__alltraps>

c0102fe6 <vector150>:
.globl vector150
vector150:
  pushl $0
c0102fe6:	6a 00                	push   $0x0
  pushl $150
c0102fe8:	68 96 00 00 00       	push   $0x96
  jmp __alltraps
c0102fed:	e9 52 fa ff ff       	jmp    c0102a44 <__alltraps>

c0102ff2 <vector151>:
.globl vector151
vector151:
  pushl $0
c0102ff2:	6a 00                	push   $0x0
  pushl $151
c0102ff4:	68 97 00 00 00       	push   $0x97
  jmp __alltraps
c0102ff9:	e9 46 fa ff ff       	jmp    c0102a44 <__alltraps>

c0102ffe <vector152>:
.globl vector152
vector152:
  pushl $0
c0102ffe:	6a 00                	push   $0x0
  pushl $152
c0103000:	68 98 00 00 00       	push   $0x98
  jmp __alltraps
c0103005:	e9 3a fa ff ff       	jmp    c0102a44 <__alltraps>

c010300a <vector153>:
.globl vector153
vector153:
  pushl $0
c010300a:	6a 00                	push   $0x0
  pushl $153
c010300c:	68 99 00 00 00       	push   $0x99
  jmp __alltraps
c0103011:	e9 2e fa ff ff       	jmp    c0102a44 <__alltraps>

c0103016 <vector154>:
.globl vector154
vector154:
  pushl $0
c0103016:	6a 00                	push   $0x0
  pushl $154
c0103018:	68 9a 00 00 00       	push   $0x9a
  jmp __alltraps
c010301d:	e9 22 fa ff ff       	jmp    c0102a44 <__alltraps>

c0103022 <vector155>:
.globl vector155
vector155:
  pushl $0
c0103022:	6a 00                	push   $0x0
  pushl $155
c0103024:	68 9b 00 00 00       	push   $0x9b
  jmp __alltraps
c0103029:	e9 16 fa ff ff       	jmp    c0102a44 <__alltraps>

c010302e <vector156>:
.globl vector156
vector156:
  pushl $0
c010302e:	6a 00                	push   $0x0
  pushl $156
c0103030:	68 9c 00 00 00       	push   $0x9c
  jmp __alltraps
c0103035:	e9 0a fa ff ff       	jmp    c0102a44 <__alltraps>

c010303a <vector157>:
.globl vector157
vector157:
  pushl $0
c010303a:	6a 00                	push   $0x0
  pushl $157
c010303c:	68 9d 00 00 00       	push   $0x9d
  jmp __alltraps
c0103041:	e9 fe f9 ff ff       	jmp    c0102a44 <__alltraps>

c0103046 <vector158>:
.globl vector158
vector158:
  pushl $0
c0103046:	6a 00                	push   $0x0
  pushl $158
c0103048:	68 9e 00 00 00       	push   $0x9e
  jmp __alltraps
c010304d:	e9 f2 f9 ff ff       	jmp    c0102a44 <__alltraps>

c0103052 <vector159>:
.globl vector159
vector159:
  pushl $0
c0103052:	6a 00                	push   $0x0
  pushl $159
c0103054:	68 9f 00 00 00       	push   $0x9f
  jmp __alltraps
c0103059:	e9 e6 f9 ff ff       	jmp    c0102a44 <__alltraps>

c010305e <vector160>:
.globl vector160
vector160:
  pushl $0
c010305e:	6a 00                	push   $0x0
  pushl $160
c0103060:	68 a0 00 00 00       	push   $0xa0
  jmp __alltraps
c0103065:	e9 da f9 ff ff       	jmp    c0102a44 <__alltraps>

c010306a <vector161>:
.globl vector161
vector161:
  pushl $0
c010306a:	6a 00                	push   $0x0
  pushl $161
c010306c:	68 a1 00 00 00       	push   $0xa1
  jmp __alltraps
c0103071:	e9 ce f9 ff ff       	jmp    c0102a44 <__alltraps>

c0103076 <vector162>:
.globl vector162
vector162:
  pushl $0
c0103076:	6a 00                	push   $0x0
  pushl $162
c0103078:	68 a2 00 00 00       	push   $0xa2
  jmp __alltraps
c010307d:	e9 c2 f9 ff ff       	jmp    c0102a44 <__alltraps>

c0103082 <vector163>:
.globl vector163
vector163:
  pushl $0
c0103082:	6a 00                	push   $0x0
  pushl $163
c0103084:	68 a3 00 00 00       	push   $0xa3
  jmp __alltraps
c0103089:	e9 b6 f9 ff ff       	jmp    c0102a44 <__alltraps>

c010308e <vector164>:
.globl vector164
vector164:
  pushl $0
c010308e:	6a 00                	push   $0x0
  pushl $164
c0103090:	68 a4 00 00 00       	push   $0xa4
  jmp __alltraps
c0103095:	e9 aa f9 ff ff       	jmp    c0102a44 <__alltraps>

c010309a <vector165>:
.globl vector165
vector165:
  pushl $0
c010309a:	6a 00                	push   $0x0
  pushl $165
c010309c:	68 a5 00 00 00       	push   $0xa5
  jmp __alltraps
c01030a1:	e9 9e f9 ff ff       	jmp    c0102a44 <__alltraps>

c01030a6 <vector166>:
.globl vector166
vector166:
  pushl $0
c01030a6:	6a 00                	push   $0x0
  pushl $166
c01030a8:	68 a6 00 00 00       	push   $0xa6
  jmp __alltraps
c01030ad:	e9 92 f9 ff ff       	jmp    c0102a44 <__alltraps>

c01030b2 <vector167>:
.globl vector167
vector167:
  pushl $0
c01030b2:	6a 00                	push   $0x0
  pushl $167
c01030b4:	68 a7 00 00 00       	push   $0xa7
  jmp __alltraps
c01030b9:	e9 86 f9 ff ff       	jmp    c0102a44 <__alltraps>

c01030be <vector168>:
.globl vector168
vector168:
  pushl $0
c01030be:	6a 00                	push   $0x0
  pushl $168
c01030c0:	68 a8 00 00 00       	push   $0xa8
  jmp __alltraps
c01030c5:	e9 7a f9 ff ff       	jmp    c0102a44 <__alltraps>

c01030ca <vector169>:
.globl vector169
vector169:
  pushl $0
c01030ca:	6a 00                	push   $0x0
  pushl $169
c01030cc:	68 a9 00 00 00       	push   $0xa9
  jmp __alltraps
c01030d1:	e9 6e f9 ff ff       	jmp    c0102a44 <__alltraps>

c01030d6 <vector170>:
.globl vector170
vector170:
  pushl $0
c01030d6:	6a 00                	push   $0x0
  pushl $170
c01030d8:	68 aa 00 00 00       	push   $0xaa
  jmp __alltraps
c01030dd:	e9 62 f9 ff ff       	jmp    c0102a44 <__alltraps>

c01030e2 <vector171>:
.globl vector171
vector171:
  pushl $0
c01030e2:	6a 00                	push   $0x0
  pushl $171
c01030e4:	68 ab 00 00 00       	push   $0xab
  jmp __alltraps
c01030e9:	e9 56 f9 ff ff       	jmp    c0102a44 <__alltraps>

c01030ee <vector172>:
.globl vector172
vector172:
  pushl $0
c01030ee:	6a 00                	push   $0x0
  pushl $172
c01030f0:	68 ac 00 00 00       	push   $0xac
  jmp __alltraps
c01030f5:	e9 4a f9 ff ff       	jmp    c0102a44 <__alltraps>

c01030fa <vector173>:
.globl vector173
vector173:
  pushl $0
c01030fa:	6a 00                	push   $0x0
  pushl $173
c01030fc:	68 ad 00 00 00       	push   $0xad
  jmp __alltraps
c0103101:	e9 3e f9 ff ff       	jmp    c0102a44 <__alltraps>

c0103106 <vector174>:
.globl vector174
vector174:
  pushl $0
c0103106:	6a 00                	push   $0x0
  pushl $174
c0103108:	68 ae 00 00 00       	push   $0xae
  jmp __alltraps
c010310d:	e9 32 f9 ff ff       	jmp    c0102a44 <__alltraps>

c0103112 <vector175>:
.globl vector175
vector175:
  pushl $0
c0103112:	6a 00                	push   $0x0
  pushl $175
c0103114:	68 af 00 00 00       	push   $0xaf
  jmp __alltraps
c0103119:	e9 26 f9 ff ff       	jmp    c0102a44 <__alltraps>

c010311e <vector176>:
.globl vector176
vector176:
  pushl $0
c010311e:	6a 00                	push   $0x0
  pushl $176
c0103120:	68 b0 00 00 00       	push   $0xb0
  jmp __alltraps
c0103125:	e9 1a f9 ff ff       	jmp    c0102a44 <__alltraps>

c010312a <vector177>:
.globl vector177
vector177:
  pushl $0
c010312a:	6a 00                	push   $0x0
  pushl $177
c010312c:	68 b1 00 00 00       	push   $0xb1
  jmp __alltraps
c0103131:	e9 0e f9 ff ff       	jmp    c0102a44 <__alltraps>

c0103136 <vector178>:
.globl vector178
vector178:
  pushl $0
c0103136:	6a 00                	push   $0x0
  pushl $178
c0103138:	68 b2 00 00 00       	push   $0xb2
  jmp __alltraps
c010313d:	e9 02 f9 ff ff       	jmp    c0102a44 <__alltraps>

c0103142 <vector179>:
.globl vector179
vector179:
  pushl $0
c0103142:	6a 00                	push   $0x0
  pushl $179
c0103144:	68 b3 00 00 00       	push   $0xb3
  jmp __alltraps
c0103149:	e9 f6 f8 ff ff       	jmp    c0102a44 <__alltraps>

c010314e <vector180>:
.globl vector180
vector180:
  pushl $0
c010314e:	6a 00                	push   $0x0
  pushl $180
c0103150:	68 b4 00 00 00       	push   $0xb4
  jmp __alltraps
c0103155:	e9 ea f8 ff ff       	jmp    c0102a44 <__alltraps>

c010315a <vector181>:
.globl vector181
vector181:
  pushl $0
c010315a:	6a 00                	push   $0x0
  pushl $181
c010315c:	68 b5 00 00 00       	push   $0xb5
  jmp __alltraps
c0103161:	e9 de f8 ff ff       	jmp    c0102a44 <__alltraps>

c0103166 <vector182>:
.globl vector182
vector182:
  pushl $0
c0103166:	6a 00                	push   $0x0
  pushl $182
c0103168:	68 b6 00 00 00       	push   $0xb6
  jmp __alltraps
c010316d:	e9 d2 f8 ff ff       	jmp    c0102a44 <__alltraps>

c0103172 <vector183>:
.globl vector183
vector183:
  pushl $0
c0103172:	6a 00                	push   $0x0
  pushl $183
c0103174:	68 b7 00 00 00       	push   $0xb7
  jmp __alltraps
c0103179:	e9 c6 f8 ff ff       	jmp    c0102a44 <__alltraps>

c010317e <vector184>:
.globl vector184
vector184:
  pushl $0
c010317e:	6a 00                	push   $0x0
  pushl $184
c0103180:	68 b8 00 00 00       	push   $0xb8
  jmp __alltraps
c0103185:	e9 ba f8 ff ff       	jmp    c0102a44 <__alltraps>

c010318a <vector185>:
.globl vector185
vector185:
  pushl $0
c010318a:	6a 00                	push   $0x0
  pushl $185
c010318c:	68 b9 00 00 00       	push   $0xb9
  jmp __alltraps
c0103191:	e9 ae f8 ff ff       	jmp    c0102a44 <__alltraps>

c0103196 <vector186>:
.globl vector186
vector186:
  pushl $0
c0103196:	6a 00                	push   $0x0
  pushl $186
c0103198:	68 ba 00 00 00       	push   $0xba
  jmp __alltraps
c010319d:	e9 a2 f8 ff ff       	jmp    c0102a44 <__alltraps>

c01031a2 <vector187>:
.globl vector187
vector187:
  pushl $0
c01031a2:	6a 00                	push   $0x0
  pushl $187
c01031a4:	68 bb 00 00 00       	push   $0xbb
  jmp __alltraps
c01031a9:	e9 96 f8 ff ff       	jmp    c0102a44 <__alltraps>

c01031ae <vector188>:
.globl vector188
vector188:
  pushl $0
c01031ae:	6a 00                	push   $0x0
  pushl $188
c01031b0:	68 bc 00 00 00       	push   $0xbc
  jmp __alltraps
c01031b5:	e9 8a f8 ff ff       	jmp    c0102a44 <__alltraps>

c01031ba <vector189>:
.globl vector189
vector189:
  pushl $0
c01031ba:	6a 00                	push   $0x0
  pushl $189
c01031bc:	68 bd 00 00 00       	push   $0xbd
  jmp __alltraps
c01031c1:	e9 7e f8 ff ff       	jmp    c0102a44 <__alltraps>

c01031c6 <vector190>:
.globl vector190
vector190:
  pushl $0
c01031c6:	6a 00                	push   $0x0
  pushl $190
c01031c8:	68 be 00 00 00       	push   $0xbe
  jmp __alltraps
c01031cd:	e9 72 f8 ff ff       	jmp    c0102a44 <__alltraps>

c01031d2 <vector191>:
.globl vector191
vector191:
  pushl $0
c01031d2:	6a 00                	push   $0x0
  pushl $191
c01031d4:	68 bf 00 00 00       	push   $0xbf
  jmp __alltraps
c01031d9:	e9 66 f8 ff ff       	jmp    c0102a44 <__alltraps>

c01031de <vector192>:
.globl vector192
vector192:
  pushl $0
c01031de:	6a 00                	push   $0x0
  pushl $192
c01031e0:	68 c0 00 00 00       	push   $0xc0
  jmp __alltraps
c01031e5:	e9 5a f8 ff ff       	jmp    c0102a44 <__alltraps>

c01031ea <vector193>:
.globl vector193
vector193:
  pushl $0
c01031ea:	6a 00                	push   $0x0
  pushl $193
c01031ec:	68 c1 00 00 00       	push   $0xc1
  jmp __alltraps
c01031f1:	e9 4e f8 ff ff       	jmp    c0102a44 <__alltraps>

c01031f6 <vector194>:
.globl vector194
vector194:
  pushl $0
c01031f6:	6a 00                	push   $0x0
  pushl $194
c01031f8:	68 c2 00 00 00       	push   $0xc2
  jmp __alltraps
c01031fd:	e9 42 f8 ff ff       	jmp    c0102a44 <__alltraps>

c0103202 <vector195>:
.globl vector195
vector195:
  pushl $0
c0103202:	6a 00                	push   $0x0
  pushl $195
c0103204:	68 c3 00 00 00       	push   $0xc3
  jmp __alltraps
c0103209:	e9 36 f8 ff ff       	jmp    c0102a44 <__alltraps>

c010320e <vector196>:
.globl vector196
vector196:
  pushl $0
c010320e:	6a 00                	push   $0x0
  pushl $196
c0103210:	68 c4 00 00 00       	push   $0xc4
  jmp __alltraps
c0103215:	e9 2a f8 ff ff       	jmp    c0102a44 <__alltraps>

c010321a <vector197>:
.globl vector197
vector197:
  pushl $0
c010321a:	6a 00                	push   $0x0
  pushl $197
c010321c:	68 c5 00 00 00       	push   $0xc5
  jmp __alltraps
c0103221:	e9 1e f8 ff ff       	jmp    c0102a44 <__alltraps>

c0103226 <vector198>:
.globl vector198
vector198:
  pushl $0
c0103226:	6a 00                	push   $0x0
  pushl $198
c0103228:	68 c6 00 00 00       	push   $0xc6
  jmp __alltraps
c010322d:	e9 12 f8 ff ff       	jmp    c0102a44 <__alltraps>

c0103232 <vector199>:
.globl vector199
vector199:
  pushl $0
c0103232:	6a 00                	push   $0x0
  pushl $199
c0103234:	68 c7 00 00 00       	push   $0xc7
  jmp __alltraps
c0103239:	e9 06 f8 ff ff       	jmp    c0102a44 <__alltraps>

c010323e <vector200>:
.globl vector200
vector200:
  pushl $0
c010323e:	6a 00                	push   $0x0
  pushl $200
c0103240:	68 c8 00 00 00       	push   $0xc8
  jmp __alltraps
c0103245:	e9 fa f7 ff ff       	jmp    c0102a44 <__alltraps>

c010324a <vector201>:
.globl vector201
vector201:
  pushl $0
c010324a:	6a 00                	push   $0x0
  pushl $201
c010324c:	68 c9 00 00 00       	push   $0xc9
  jmp __alltraps
c0103251:	e9 ee f7 ff ff       	jmp    c0102a44 <__alltraps>

c0103256 <vector202>:
.globl vector202
vector202:
  pushl $0
c0103256:	6a 00                	push   $0x0
  pushl $202
c0103258:	68 ca 00 00 00       	push   $0xca
  jmp __alltraps
c010325d:	e9 e2 f7 ff ff       	jmp    c0102a44 <__alltraps>

c0103262 <vector203>:
.globl vector203
vector203:
  pushl $0
c0103262:	6a 00                	push   $0x0
  pushl $203
c0103264:	68 cb 00 00 00       	push   $0xcb
  jmp __alltraps
c0103269:	e9 d6 f7 ff ff       	jmp    c0102a44 <__alltraps>

c010326e <vector204>:
.globl vector204
vector204:
  pushl $0
c010326e:	6a 00                	push   $0x0
  pushl $204
c0103270:	68 cc 00 00 00       	push   $0xcc
  jmp __alltraps
c0103275:	e9 ca f7 ff ff       	jmp    c0102a44 <__alltraps>

c010327a <vector205>:
.globl vector205
vector205:
  pushl $0
c010327a:	6a 00                	push   $0x0
  pushl $205
c010327c:	68 cd 00 00 00       	push   $0xcd
  jmp __alltraps
c0103281:	e9 be f7 ff ff       	jmp    c0102a44 <__alltraps>

c0103286 <vector206>:
.globl vector206
vector206:
  pushl $0
c0103286:	6a 00                	push   $0x0
  pushl $206
c0103288:	68 ce 00 00 00       	push   $0xce
  jmp __alltraps
c010328d:	e9 b2 f7 ff ff       	jmp    c0102a44 <__alltraps>

c0103292 <vector207>:
.globl vector207
vector207:
  pushl $0
c0103292:	6a 00                	push   $0x0
  pushl $207
c0103294:	68 cf 00 00 00       	push   $0xcf
  jmp __alltraps
c0103299:	e9 a6 f7 ff ff       	jmp    c0102a44 <__alltraps>

c010329e <vector208>:
.globl vector208
vector208:
  pushl $0
c010329e:	6a 00                	push   $0x0
  pushl $208
c01032a0:	68 d0 00 00 00       	push   $0xd0
  jmp __alltraps
c01032a5:	e9 9a f7 ff ff       	jmp    c0102a44 <__alltraps>

c01032aa <vector209>:
.globl vector209
vector209:
  pushl $0
c01032aa:	6a 00                	push   $0x0
  pushl $209
c01032ac:	68 d1 00 00 00       	push   $0xd1
  jmp __alltraps
c01032b1:	e9 8e f7 ff ff       	jmp    c0102a44 <__alltraps>

c01032b6 <vector210>:
.globl vector210
vector210:
  pushl $0
c01032b6:	6a 00                	push   $0x0
  pushl $210
c01032b8:	68 d2 00 00 00       	push   $0xd2
  jmp __alltraps
c01032bd:	e9 82 f7 ff ff       	jmp    c0102a44 <__alltraps>

c01032c2 <vector211>:
.globl vector211
vector211:
  pushl $0
c01032c2:	6a 00                	push   $0x0
  pushl $211
c01032c4:	68 d3 00 00 00       	push   $0xd3
  jmp __alltraps
c01032c9:	e9 76 f7 ff ff       	jmp    c0102a44 <__alltraps>

c01032ce <vector212>:
.globl vector212
vector212:
  pushl $0
c01032ce:	6a 00                	push   $0x0
  pushl $212
c01032d0:	68 d4 00 00 00       	push   $0xd4
  jmp __alltraps
c01032d5:	e9 6a f7 ff ff       	jmp    c0102a44 <__alltraps>

c01032da <vector213>:
.globl vector213
vector213:
  pushl $0
c01032da:	6a 00                	push   $0x0
  pushl $213
c01032dc:	68 d5 00 00 00       	push   $0xd5
  jmp __alltraps
c01032e1:	e9 5e f7 ff ff       	jmp    c0102a44 <__alltraps>

c01032e6 <vector214>:
.globl vector214
vector214:
  pushl $0
c01032e6:	6a 00                	push   $0x0
  pushl $214
c01032e8:	68 d6 00 00 00       	push   $0xd6
  jmp __alltraps
c01032ed:	e9 52 f7 ff ff       	jmp    c0102a44 <__alltraps>

c01032f2 <vector215>:
.globl vector215
vector215:
  pushl $0
c01032f2:	6a 00                	push   $0x0
  pushl $215
c01032f4:	68 d7 00 00 00       	push   $0xd7
  jmp __alltraps
c01032f9:	e9 46 f7 ff ff       	jmp    c0102a44 <__alltraps>

c01032fe <vector216>:
.globl vector216
vector216:
  pushl $0
c01032fe:	6a 00                	push   $0x0
  pushl $216
c0103300:	68 d8 00 00 00       	push   $0xd8
  jmp __alltraps
c0103305:	e9 3a f7 ff ff       	jmp    c0102a44 <__alltraps>

c010330a <vector217>:
.globl vector217
vector217:
  pushl $0
c010330a:	6a 00                	push   $0x0
  pushl $217
c010330c:	68 d9 00 00 00       	push   $0xd9
  jmp __alltraps
c0103311:	e9 2e f7 ff ff       	jmp    c0102a44 <__alltraps>

c0103316 <vector218>:
.globl vector218
vector218:
  pushl $0
c0103316:	6a 00                	push   $0x0
  pushl $218
c0103318:	68 da 00 00 00       	push   $0xda
  jmp __alltraps
c010331d:	e9 22 f7 ff ff       	jmp    c0102a44 <__alltraps>

c0103322 <vector219>:
.globl vector219
vector219:
  pushl $0
c0103322:	6a 00                	push   $0x0
  pushl $219
c0103324:	68 db 00 00 00       	push   $0xdb
  jmp __alltraps
c0103329:	e9 16 f7 ff ff       	jmp    c0102a44 <__alltraps>

c010332e <vector220>:
.globl vector220
vector220:
  pushl $0
c010332e:	6a 00                	push   $0x0
  pushl $220
c0103330:	68 dc 00 00 00       	push   $0xdc
  jmp __alltraps
c0103335:	e9 0a f7 ff ff       	jmp    c0102a44 <__alltraps>

c010333a <vector221>:
.globl vector221
vector221:
  pushl $0
c010333a:	6a 00                	push   $0x0
  pushl $221
c010333c:	68 dd 00 00 00       	push   $0xdd
  jmp __alltraps
c0103341:	e9 fe f6 ff ff       	jmp    c0102a44 <__alltraps>

c0103346 <vector222>:
.globl vector222
vector222:
  pushl $0
c0103346:	6a 00                	push   $0x0
  pushl $222
c0103348:	68 de 00 00 00       	push   $0xde
  jmp __alltraps
c010334d:	e9 f2 f6 ff ff       	jmp    c0102a44 <__alltraps>

c0103352 <vector223>:
.globl vector223
vector223:
  pushl $0
c0103352:	6a 00                	push   $0x0
  pushl $223
c0103354:	68 df 00 00 00       	push   $0xdf
  jmp __alltraps
c0103359:	e9 e6 f6 ff ff       	jmp    c0102a44 <__alltraps>

c010335e <vector224>:
.globl vector224
vector224:
  pushl $0
c010335e:	6a 00                	push   $0x0
  pushl $224
c0103360:	68 e0 00 00 00       	push   $0xe0
  jmp __alltraps
c0103365:	e9 da f6 ff ff       	jmp    c0102a44 <__alltraps>

c010336a <vector225>:
.globl vector225
vector225:
  pushl $0
c010336a:	6a 00                	push   $0x0
  pushl $225
c010336c:	68 e1 00 00 00       	push   $0xe1
  jmp __alltraps
c0103371:	e9 ce f6 ff ff       	jmp    c0102a44 <__alltraps>

c0103376 <vector226>:
.globl vector226
vector226:
  pushl $0
c0103376:	6a 00                	push   $0x0
  pushl $226
c0103378:	68 e2 00 00 00       	push   $0xe2
  jmp __alltraps
c010337d:	e9 c2 f6 ff ff       	jmp    c0102a44 <__alltraps>

c0103382 <vector227>:
.globl vector227
vector227:
  pushl $0
c0103382:	6a 00                	push   $0x0
  pushl $227
c0103384:	68 e3 00 00 00       	push   $0xe3
  jmp __alltraps
c0103389:	e9 b6 f6 ff ff       	jmp    c0102a44 <__alltraps>

c010338e <vector228>:
.globl vector228
vector228:
  pushl $0
c010338e:	6a 00                	push   $0x0
  pushl $228
c0103390:	68 e4 00 00 00       	push   $0xe4
  jmp __alltraps
c0103395:	e9 aa f6 ff ff       	jmp    c0102a44 <__alltraps>

c010339a <vector229>:
.globl vector229
vector229:
  pushl $0
c010339a:	6a 00                	push   $0x0
  pushl $229
c010339c:	68 e5 00 00 00       	push   $0xe5
  jmp __alltraps
c01033a1:	e9 9e f6 ff ff       	jmp    c0102a44 <__alltraps>

c01033a6 <vector230>:
.globl vector230
vector230:
  pushl $0
c01033a6:	6a 00                	push   $0x0
  pushl $230
c01033a8:	68 e6 00 00 00       	push   $0xe6
  jmp __alltraps
c01033ad:	e9 92 f6 ff ff       	jmp    c0102a44 <__alltraps>

c01033b2 <vector231>:
.globl vector231
vector231:
  pushl $0
c01033b2:	6a 00                	push   $0x0
  pushl $231
c01033b4:	68 e7 00 00 00       	push   $0xe7
  jmp __alltraps
c01033b9:	e9 86 f6 ff ff       	jmp    c0102a44 <__alltraps>

c01033be <vector232>:
.globl vector232
vector232:
  pushl $0
c01033be:	6a 00                	push   $0x0
  pushl $232
c01033c0:	68 e8 00 00 00       	push   $0xe8
  jmp __alltraps
c01033c5:	e9 7a f6 ff ff       	jmp    c0102a44 <__alltraps>

c01033ca <vector233>:
.globl vector233
vector233:
  pushl $0
c01033ca:	6a 00                	push   $0x0
  pushl $233
c01033cc:	68 e9 00 00 00       	push   $0xe9
  jmp __alltraps
c01033d1:	e9 6e f6 ff ff       	jmp    c0102a44 <__alltraps>

c01033d6 <vector234>:
.globl vector234
vector234:
  pushl $0
c01033d6:	6a 00                	push   $0x0
  pushl $234
c01033d8:	68 ea 00 00 00       	push   $0xea
  jmp __alltraps
c01033dd:	e9 62 f6 ff ff       	jmp    c0102a44 <__alltraps>

c01033e2 <vector235>:
.globl vector235
vector235:
  pushl $0
c01033e2:	6a 00                	push   $0x0
  pushl $235
c01033e4:	68 eb 00 00 00       	push   $0xeb
  jmp __alltraps
c01033e9:	e9 56 f6 ff ff       	jmp    c0102a44 <__alltraps>

c01033ee <vector236>:
.globl vector236
vector236:
  pushl $0
c01033ee:	6a 00                	push   $0x0
  pushl $236
c01033f0:	68 ec 00 00 00       	push   $0xec
  jmp __alltraps
c01033f5:	e9 4a f6 ff ff       	jmp    c0102a44 <__alltraps>

c01033fa <vector237>:
.globl vector237
vector237:
  pushl $0
c01033fa:	6a 00                	push   $0x0
  pushl $237
c01033fc:	68 ed 00 00 00       	push   $0xed
  jmp __alltraps
c0103401:	e9 3e f6 ff ff       	jmp    c0102a44 <__alltraps>

c0103406 <vector238>:
.globl vector238
vector238:
  pushl $0
c0103406:	6a 00                	push   $0x0
  pushl $238
c0103408:	68 ee 00 00 00       	push   $0xee
  jmp __alltraps
c010340d:	e9 32 f6 ff ff       	jmp    c0102a44 <__alltraps>

c0103412 <vector239>:
.globl vector239
vector239:
  pushl $0
c0103412:	6a 00                	push   $0x0
  pushl $239
c0103414:	68 ef 00 00 00       	push   $0xef
  jmp __alltraps
c0103419:	e9 26 f6 ff ff       	jmp    c0102a44 <__alltraps>

c010341e <vector240>:
.globl vector240
vector240:
  pushl $0
c010341e:	6a 00                	push   $0x0
  pushl $240
c0103420:	68 f0 00 00 00       	push   $0xf0
  jmp __alltraps
c0103425:	e9 1a f6 ff ff       	jmp    c0102a44 <__alltraps>

c010342a <vector241>:
.globl vector241
vector241:
  pushl $0
c010342a:	6a 00                	push   $0x0
  pushl $241
c010342c:	68 f1 00 00 00       	push   $0xf1
  jmp __alltraps
c0103431:	e9 0e f6 ff ff       	jmp    c0102a44 <__alltraps>

c0103436 <vector242>:
.globl vector242
vector242:
  pushl $0
c0103436:	6a 00                	push   $0x0
  pushl $242
c0103438:	68 f2 00 00 00       	push   $0xf2
  jmp __alltraps
c010343d:	e9 02 f6 ff ff       	jmp    c0102a44 <__alltraps>

c0103442 <vector243>:
.globl vector243
vector243:
  pushl $0
c0103442:	6a 00                	push   $0x0
  pushl $243
c0103444:	68 f3 00 00 00       	push   $0xf3
  jmp __alltraps
c0103449:	e9 f6 f5 ff ff       	jmp    c0102a44 <__alltraps>

c010344e <vector244>:
.globl vector244
vector244:
  pushl $0
c010344e:	6a 00                	push   $0x0
  pushl $244
c0103450:	68 f4 00 00 00       	push   $0xf4
  jmp __alltraps
c0103455:	e9 ea f5 ff ff       	jmp    c0102a44 <__alltraps>

c010345a <vector245>:
.globl vector245
vector245:
  pushl $0
c010345a:	6a 00                	push   $0x0
  pushl $245
c010345c:	68 f5 00 00 00       	push   $0xf5
  jmp __alltraps
c0103461:	e9 de f5 ff ff       	jmp    c0102a44 <__alltraps>

c0103466 <vector246>:
.globl vector246
vector246:
  pushl $0
c0103466:	6a 00                	push   $0x0
  pushl $246
c0103468:	68 f6 00 00 00       	push   $0xf6
  jmp __alltraps
c010346d:	e9 d2 f5 ff ff       	jmp    c0102a44 <__alltraps>

c0103472 <vector247>:
.globl vector247
vector247:
  pushl $0
c0103472:	6a 00                	push   $0x0
  pushl $247
c0103474:	68 f7 00 00 00       	push   $0xf7
  jmp __alltraps
c0103479:	e9 c6 f5 ff ff       	jmp    c0102a44 <__alltraps>

c010347e <vector248>:
.globl vector248
vector248:
  pushl $0
c010347e:	6a 00                	push   $0x0
  pushl $248
c0103480:	68 f8 00 00 00       	push   $0xf8
  jmp __alltraps
c0103485:	e9 ba f5 ff ff       	jmp    c0102a44 <__alltraps>

c010348a <vector249>:
.globl vector249
vector249:
  pushl $0
c010348a:	6a 00                	push   $0x0
  pushl $249
c010348c:	68 f9 00 00 00       	push   $0xf9
  jmp __alltraps
c0103491:	e9 ae f5 ff ff       	jmp    c0102a44 <__alltraps>

c0103496 <vector250>:
.globl vector250
vector250:
  pushl $0
c0103496:	6a 00                	push   $0x0
  pushl $250
c0103498:	68 fa 00 00 00       	push   $0xfa
  jmp __alltraps
c010349d:	e9 a2 f5 ff ff       	jmp    c0102a44 <__alltraps>

c01034a2 <vector251>:
.globl vector251
vector251:
  pushl $0
c01034a2:	6a 00                	push   $0x0
  pushl $251
c01034a4:	68 fb 00 00 00       	push   $0xfb
  jmp __alltraps
c01034a9:	e9 96 f5 ff ff       	jmp    c0102a44 <__alltraps>

c01034ae <vector252>:
.globl vector252
vector252:
  pushl $0
c01034ae:	6a 00                	push   $0x0
  pushl $252
c01034b0:	68 fc 00 00 00       	push   $0xfc
  jmp __alltraps
c01034b5:	e9 8a f5 ff ff       	jmp    c0102a44 <__alltraps>

c01034ba <vector253>:
.globl vector253
vector253:
  pushl $0
c01034ba:	6a 00                	push   $0x0
  pushl $253
c01034bc:	68 fd 00 00 00       	push   $0xfd
  jmp __alltraps
c01034c1:	e9 7e f5 ff ff       	jmp    c0102a44 <__alltraps>

c01034c6 <vector254>:
.globl vector254
vector254:
  pushl $0
c01034c6:	6a 00                	push   $0x0
  pushl $254
c01034c8:	68 fe 00 00 00       	push   $0xfe
  jmp __alltraps
c01034cd:	e9 72 f5 ff ff       	jmp    c0102a44 <__alltraps>

c01034d2 <vector255>:
.globl vector255
vector255:
  pushl $0
c01034d2:	6a 00                	push   $0x0
  pushl $255
c01034d4:	68 ff 00 00 00       	push   $0xff
  jmp __alltraps
c01034d9:	e9 66 f5 ff ff       	jmp    c0102a44 <__alltraps>

c01034de <page2ppn>:

extern struct Page *pages;
extern size_t npage;

static inline ppn_t
page2ppn(struct Page *page) {
c01034de:	55                   	push   %ebp
c01034df:	89 e5                	mov    %esp,%ebp
    return page - pages;
c01034e1:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c01034e7:	8b 45 08             	mov    0x8(%ebp),%eax
c01034ea:	29 d0                	sub    %edx,%eax
c01034ec:	c1 f8 05             	sar    $0x5,%eax
}
c01034ef:	5d                   	pop    %ebp
c01034f0:	c3                   	ret    

c01034f1 <page2pa>:

static inline uintptr_t
page2pa(struct Page *page) {
c01034f1:	55                   	push   %ebp
c01034f2:	89 e5                	mov    %esp,%ebp
c01034f4:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c01034f7:	8b 45 08             	mov    0x8(%ebp),%eax
c01034fa:	89 04 24             	mov    %eax,(%esp)
c01034fd:	e8 dc ff ff ff       	call   c01034de <page2ppn>
c0103502:	c1 e0 0c             	shl    $0xc,%eax
}
c0103505:	89 ec                	mov    %ebp,%esp
c0103507:	5d                   	pop    %ebp
c0103508:	c3                   	ret    

c0103509 <page_ref>:
pde2page(pde_t pde) {
    return pa2page(PDE_ADDR(pde));
}

static inline int
page_ref(struct Page *page) {
c0103509:	55                   	push   %ebp
c010350a:	89 e5                	mov    %esp,%ebp
    return page->ref;
c010350c:	8b 45 08             	mov    0x8(%ebp),%eax
c010350f:	8b 00                	mov    (%eax),%eax
}
c0103511:	5d                   	pop    %ebp
c0103512:	c3                   	ret    

c0103513 <set_page_ref>:

static inline void
set_page_ref(struct Page *page, int val) {
c0103513:	55                   	push   %ebp
c0103514:	89 e5                	mov    %esp,%ebp
    page->ref = val;
c0103516:	8b 45 08             	mov    0x8(%ebp),%eax
c0103519:	8b 55 0c             	mov    0xc(%ebp),%edx
c010351c:	89 10                	mov    %edx,(%eax)
}
c010351e:	90                   	nop
c010351f:	5d                   	pop    %ebp
c0103520:	c3                   	ret    

c0103521 <default_init>:
#define nr_free (free_area.nr_free)

//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。
//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。
static void
default_init(void) {
c0103521:	55                   	push   %ebp
c0103522:	89 e5                	mov    %esp,%ebp
c0103524:	83 ec 10             	sub    $0x10,%esp
c0103527:	c7 45 fc 84 3f 1a c0 	movl   $0xc01a3f84,-0x4(%ebp)
 * list_init - initialize a new entry
 * @elm:        new entry to be initialized
 * */
static inline void
list_init(list_entry_t *elm) {
    elm->prev = elm->next = elm;
c010352e:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0103531:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0103534:	89 50 04             	mov    %edx,0x4(%eax)
c0103537:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010353a:	8b 50 04             	mov    0x4(%eax),%edx
c010353d:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0103540:	89 10                	mov    %edx,(%eax)
}
c0103542:	90                   	nop
    list_init(&free_list);
    nr_free = 0;
c0103543:	c7 05 8c 3f 1a c0 00 	movl   $0x0,0xc01a3f8c
c010354a:	00 00 00 
}
c010354d:	90                   	nop
c010354e:	89 ec                	mov    %ebp,%esp
c0103550:	5d                   	pop    %ebp
c0103551:	c3                   	ret    

c0103552 <default_init_memmap>:

//用于初始化一段连续的物理页，并将它们加入到空闲内存管理系统中.
//struct Page *base：指向要初始化的页块的起始地址。size_t n：要初始化的页的数量。
static void
default_init_memmap(struct Page *base, size_t n) {
c0103552:	55                   	push   %ebp
c0103553:	89 e5                	mov    %esp,%ebp
c0103555:	83 ec 48             	sub    $0x48,%esp
    assert(n > 0);// 确保请求的页数大于零
c0103558:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010355c:	75 24                	jne    c0103582 <default_init_memmap+0x30>
c010355e:	c7 44 24 0c 30 c9 10 	movl   $0xc010c930,0xc(%esp)
c0103565:	c0 
c0103566:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c010356d:	c0 
c010356e:	c7 44 24 04 9a 00 00 	movl   $0x9a,0x4(%esp)
c0103575:	00 
c0103576:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c010357d:	e8 b9 d7 ff ff       	call   c0100d3b <__panic>
    struct Page *p = base;// 指向当前初始化的页
c0103582:	8b 45 08             	mov    0x8(%ebp),%eax
c0103585:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历每一页，设置其状态
    for (; p != base + n; p ++) {
c0103588:	eb 7d                	jmp    c0103607 <default_init_memmap+0xb5>
        assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留，函数将抛出错误。
c010358a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010358d:	83 c0 04             	add    $0x4,%eax
c0103590:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
c0103597:	89 45 ec             	mov    %eax,-0x14(%ebp)
 * @addr:   the address to count from
 * */
static inline bool
test_bit(int nr, volatile void *addr) {
    int oldbit;
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c010359a:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010359d:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01035a0:	0f a3 10             	bt     %edx,(%eax)
c01035a3:	19 c0                	sbb    %eax,%eax
c01035a5:	89 45 e8             	mov    %eax,-0x18(%ebp)
    return oldbit != 0;
c01035a8:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c01035ac:	0f 95 c0             	setne  %al
c01035af:	0f b6 c0             	movzbl %al,%eax
c01035b2:	85 c0                	test   %eax,%eax
c01035b4:	75 24                	jne    c01035da <default_init_memmap+0x88>
c01035b6:	c7 44 24 0c 61 c9 10 	movl   $0xc010c961,0xc(%esp)
c01035bd:	c0 
c01035be:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01035c5:	c0 
c01035c6:	c7 44 24 04 9e 00 00 	movl   $0x9e,0x4(%esp)
c01035cd:	00 
c01035ce:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01035d5:	e8 61 d7 ff ff       	call   c0100d3b <__panic>
        p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0，表示该页未分配、未使用。
c01035da:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01035dd:	c7 40 08 00 00 00 00 	movl   $0x0,0x8(%eax)
c01035e4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01035e7:	8b 50 08             	mov    0x8(%eax),%edx
c01035ea:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01035ed:	89 50 04             	mov    %edx,0x4(%eax)
        set_page_ref(p, 0);//将页的引用计数设置为 0，表明没有任何引用指向此页。
c01035f0:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01035f7:	00 
c01035f8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01035fb:	89 04 24             	mov    %eax,(%esp)
c01035fe:	e8 10 ff ff ff       	call   c0103513 <set_page_ref>
    for (; p != base + n; p ++) {
c0103603:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
c0103607:	8b 45 0c             	mov    0xc(%ebp),%eax
c010360a:	c1 e0 05             	shl    $0x5,%eax
c010360d:	89 c2                	mov    %eax,%edx
c010360f:	8b 45 08             	mov    0x8(%ebp),%eax
c0103612:	01 d0                	add    %edx,%eax
c0103614:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0103617:	0f 85 6d ff ff ff    	jne    c010358a <default_init_memmap+0x38>
    }
    // 设置第一个页的 property 为块的总数
    base->property = n;
c010361d:	8b 45 08             	mov    0x8(%ebp),%eax
c0103620:	8b 55 0c             	mov    0xc(%ebp),%edx
c0103623:	89 50 08             	mov    %edx,0x8(%eax)
    SetPageProperty(base);// 设置当前页的有效标志
c0103626:	8b 45 08             	mov    0x8(%ebp),%eax
c0103629:	83 c0 04             	add    $0x4,%eax
c010362c:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c0103633:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0103636:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0103639:	8b 55 d0             	mov    -0x30(%ebp),%edx
c010363c:	0f ab 10             	bts    %edx,(%eax)
}
c010363f:	90                   	nop
    nr_free += n;// 更新空闲页计数
c0103640:	8b 15 8c 3f 1a c0    	mov    0xc01a3f8c,%edx
c0103646:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103649:	01 d0                	add    %edx,%eax
c010364b:	a3 8c 3f 1a c0       	mov    %eax,0xc01a3f8c
    list_add_before(&free_list, &(base->page_link));// 将该块添加到空闲列表中
c0103650:	8b 45 08             	mov    0x8(%ebp),%eax
c0103653:	83 c0 0c             	add    $0xc,%eax
c0103656:	c7 45 e4 84 3f 1a c0 	movl   $0xc01a3f84,-0x1c(%ebp)
c010365d:	89 45 e0             	mov    %eax,-0x20(%ebp)
 * Insert the new element @elm *before* the element @listelm which
 * is already in the list.
 * */
static inline void
list_add_before(list_entry_t *listelm, list_entry_t *elm) {
    __list_add(elm, listelm->prev, listelm);
c0103660:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0103663:	8b 00                	mov    (%eax),%eax
c0103665:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0103668:	89 55 dc             	mov    %edx,-0x24(%ebp)
c010366b:	89 45 d8             	mov    %eax,-0x28(%ebp)
c010366e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0103671:	89 45 d4             	mov    %eax,-0x2c(%ebp)
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 * */
static inline void
__list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) {
    prev->next = next->prev = elm;
c0103674:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0103677:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010367a:	89 10                	mov    %edx,(%eax)
c010367c:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c010367f:	8b 10                	mov    (%eax),%edx
c0103681:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0103684:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0103687:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010368a:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010368d:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0103690:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0103693:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0103696:	89 10                	mov    %edx,(%eax)
}
c0103698:	90                   	nop
}
c0103699:	90                   	nop
}
c010369a:	90                   	nop
c010369b:	89 ec                	mov    %ebp,%esp
c010369d:	5d                   	pop    %ebp
c010369e:	c3                   	ret    

c010369f <default_alloc_pages>:

//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。
static struct Page *
default_alloc_pages(size_t n) {
c010369f:	55                   	push   %ebp
c01036a0:	89 e5                	mov    %esp,%ebp
c01036a2:	83 ec 68             	sub    $0x68,%esp
    assert(n > 0);// 确保请求的页数大于零
c01036a5:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c01036a9:	75 24                	jne    c01036cf <default_alloc_pages+0x30>
c01036ab:	c7 44 24 0c 30 c9 10 	movl   $0xc010c930,0xc(%esp)
c01036b2:	c0 
c01036b3:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01036ba:	c0 
c01036bb:	c7 44 24 04 ac 00 00 	movl   $0xac,0x4(%esp)
c01036c2:	00 
c01036c3:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01036ca:	e8 6c d6 ff ff       	call   c0100d3b <__panic>
    if (n > nr_free) {// 检查请求的页数是否超过空闲页数
c01036cf:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c01036d4:	39 45 08             	cmp    %eax,0x8(%ebp)
c01036d7:	76 0a                	jbe    c01036e3 <default_alloc_pages+0x44>
        return NULL;
c01036d9:	b8 00 00 00 00       	mov    $0x0,%eax
c01036de:	e9 3c 01 00 00       	jmp    c010381f <default_alloc_pages+0x180>
    }
    struct Page *page = NULL;// 初始化分配的页指针
c01036e3:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    list_entry_t *le = &free_list;// 初始化链表迭代器
c01036ea:	c7 45 f0 84 3f 1a c0 	movl   $0xc01a3f84,-0x10(%ebp)
    // 遍历空闲列表，寻找第一个满足条件的块
    while ((le = list_next(le)) != &free_list) {
c01036f1:	eb 1c                	jmp    c010370f <default_alloc_pages+0x70>
        struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体
c01036f3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01036f6:	83 e8 0c             	sub    $0xc,%eax
c01036f9:	89 45 ec             	mov    %eax,-0x14(%ebp)
        if (p->property >= n) {// 检查当前块的页数是否满足请求
c01036fc:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01036ff:	8b 40 08             	mov    0x8(%eax),%eax
c0103702:	39 45 08             	cmp    %eax,0x8(%ebp)
c0103705:	77 08                	ja     c010370f <default_alloc_pages+0x70>
            page = p;// 找到合适的块
c0103707:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010370a:	89 45 f4             	mov    %eax,-0xc(%ebp)
            break;// 退出循环
c010370d:	eb 18                	jmp    c0103727 <default_alloc_pages+0x88>
c010370f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103712:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    return listelm->next;
c0103715:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0103718:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c010371b:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010371e:	81 7d f0 84 3f 1a c0 	cmpl   $0xc01a3f84,-0x10(%ebp)
c0103725:	75 cc                	jne    c01036f3 <default_alloc_pages+0x54>
        }
    }
    if (page != NULL) {// 如果找到合适的块
c0103727:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010372b:	0f 84 eb 00 00 00    	je     c010381c <default_alloc_pages+0x17d>
        //list_del(&(page->page_link));// 从空闲列表中删除该块
        if (page->property > n) {
c0103731:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103734:	8b 40 08             	mov    0x8(%eax),%eax
c0103737:	39 45 08             	cmp    %eax,0x8(%ebp)
c010373a:	0f 83 88 00 00 00    	jae    c01037c8 <default_alloc_pages+0x129>
            struct Page *p = page + n;// 指向剩余的页
c0103740:	8b 45 08             	mov    0x8(%ebp),%eax
c0103743:	c1 e0 05             	shl    $0x5,%eax
c0103746:	89 c2                	mov    %eax,%edx
c0103748:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010374b:	01 d0                	add    %edx,%eax
c010374d:	89 45 e8             	mov    %eax,-0x18(%ebp)
            p->property = page->property - n;// 更新剩余块的页数
c0103750:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103753:	8b 40 08             	mov    0x8(%eax),%eax
c0103756:	2b 45 08             	sub    0x8(%ebp),%eax
c0103759:	89 c2                	mov    %eax,%edx
c010375b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010375e:	89 50 08             	mov    %edx,0x8(%eax)
            SetPageProperty(p);
c0103761:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0103764:	83 c0 04             	add    $0x4,%eax
c0103767:	c7 45 cc 01 00 00 00 	movl   $0x1,-0x34(%ebp)
c010376e:	89 45 c8             	mov    %eax,-0x38(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0103771:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0103774:	8b 55 cc             	mov    -0x34(%ebp),%edx
c0103777:	0f ab 10             	bts    %edx,(%eax)
}
c010377a:	90                   	nop
            list_add_after(&(page->page_link), &(p->page_link));// 将剩余块添加回空闲列表
c010377b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010377e:	83 c0 0c             	add    $0xc,%eax
c0103781:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0103784:	83 c2 0c             	add    $0xc,%edx
c0103787:	89 55 e0             	mov    %edx,-0x20(%ebp)
c010378a:	89 45 dc             	mov    %eax,-0x24(%ebp)
    __list_add(elm, listelm, listelm->next);
c010378d:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0103790:	8b 40 04             	mov    0x4(%eax),%eax
c0103793:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103796:	89 55 d8             	mov    %edx,-0x28(%ebp)
c0103799:	8b 55 e0             	mov    -0x20(%ebp),%edx
c010379c:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c010379f:	89 45 d0             	mov    %eax,-0x30(%ebp)
    prev->next = next->prev = elm;
c01037a2:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01037a5:	8b 55 d8             	mov    -0x28(%ebp),%edx
c01037a8:	89 10                	mov    %edx,(%eax)
c01037aa:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01037ad:	8b 10                	mov    (%eax),%edx
c01037af:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01037b2:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c01037b5:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01037b8:	8b 55 d0             	mov    -0x30(%ebp),%edx
c01037bb:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c01037be:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01037c1:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01037c4:	89 10                	mov    %edx,(%eax)
}
c01037c6:	90                   	nop
}
c01037c7:	90                   	nop
    }
        list_del(&(page->page_link));
c01037c8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01037cb:	83 c0 0c             	add    $0xc,%eax
c01037ce:	89 45 bc             	mov    %eax,-0x44(%ebp)
    __list_del(listelm->prev, listelm->next);
c01037d1:	8b 45 bc             	mov    -0x44(%ebp),%eax
c01037d4:	8b 40 04             	mov    0x4(%eax),%eax
c01037d7:	8b 55 bc             	mov    -0x44(%ebp),%edx
c01037da:	8b 12                	mov    (%edx),%edx
c01037dc:	89 55 b8             	mov    %edx,-0x48(%ebp)
c01037df:	89 45 b4             	mov    %eax,-0x4c(%ebp)
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 * */
static inline void
__list_del(list_entry_t *prev, list_entry_t *next) {
    prev->next = next;
c01037e2:	8b 45 b8             	mov    -0x48(%ebp),%eax
c01037e5:	8b 55 b4             	mov    -0x4c(%ebp),%edx
c01037e8:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c01037eb:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c01037ee:	8b 55 b8             	mov    -0x48(%ebp),%edx
c01037f1:	89 10                	mov    %edx,(%eax)
}
c01037f3:	90                   	nop
}
c01037f4:	90                   	nop
        nr_free -= n;// 减少空闲页的计数
c01037f5:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c01037fa:	2b 45 08             	sub    0x8(%ebp),%eax
c01037fd:	a3 8c 3f 1a c0       	mov    %eax,0xc01a3f8c
        ClearPageProperty(page);// 清除已分配页的属性
c0103802:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103805:	83 c0 04             	add    $0x4,%eax
c0103808:	c7 45 c4 01 00 00 00 	movl   $0x1,-0x3c(%ebp)
c010380f:	89 45 c0             	mov    %eax,-0x40(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0103812:	8b 45 c0             	mov    -0x40(%ebp),%eax
c0103815:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c0103818:	0f b3 10             	btr    %edx,(%eax)
}
c010381b:	90                   	nop
    }
    return page;// 返回分配的页块
c010381c:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010381f:	89 ec                	mov    %ebp,%esp
c0103821:	5d                   	pop    %ebp
c0103822:	c3                   	ret    

c0103823 <default_free_pages>:

static void
default_free_pages(struct Page *base, size_t n) {
c0103823:	55                   	push   %ebp
c0103824:	89 e5                	mov    %esp,%ebp
c0103826:	81 ec 98 00 00 00    	sub    $0x98,%esp
    assert(n > 0);// 确保请求释放的页数大于零
c010382c:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0103830:	75 24                	jne    c0103856 <default_free_pages+0x33>
c0103832:	c7 44 24 0c 30 c9 10 	movl   $0xc010c930,0xc(%esp)
c0103839:	c0 
c010383a:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103841:	c0 
c0103842:	c7 44 24 04 cb 00 00 	movl   $0xcb,0x4(%esp)
c0103849:	00 
c010384a:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103851:	e8 e5 d4 ff ff       	call   c0100d3b <__panic>
    struct Page *p = base;
c0103856:	8b 45 08             	mov    0x8(%ebp),%eax
c0103859:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历释放的页，检查状态并重置
    for (; p != base + n; p ++) {
c010385c:	e9 9d 00 00 00       	jmp    c01038fe <default_free_pages+0xdb>
        assert(!PageReserved(p) && !PageProperty(p));// 确保页没有被保留并且没有属性
c0103861:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103864:	83 c0 04             	add    $0x4,%eax
c0103867:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c010386e:	89 45 e8             	mov    %eax,-0x18(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0103871:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0103874:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0103877:	0f a3 10             	bt     %edx,(%eax)
c010387a:	19 c0                	sbb    %eax,%eax
c010387c:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    return oldbit != 0;
c010387f:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0103883:	0f 95 c0             	setne  %al
c0103886:	0f b6 c0             	movzbl %al,%eax
c0103889:	85 c0                	test   %eax,%eax
c010388b:	75 2c                	jne    c01038b9 <default_free_pages+0x96>
c010388d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103890:	83 c0 04             	add    $0x4,%eax
c0103893:	c7 45 e0 01 00 00 00 	movl   $0x1,-0x20(%ebp)
c010389a:	89 45 dc             	mov    %eax,-0x24(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c010389d:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01038a0:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01038a3:	0f a3 10             	bt     %edx,(%eax)
c01038a6:	19 c0                	sbb    %eax,%eax
c01038a8:	89 45 d8             	mov    %eax,-0x28(%ebp)
    return oldbit != 0;
c01038ab:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c01038af:	0f 95 c0             	setne  %al
c01038b2:	0f b6 c0             	movzbl %al,%eax
c01038b5:	85 c0                	test   %eax,%eax
c01038b7:	74 24                	je     c01038dd <default_free_pages+0xba>
c01038b9:	c7 44 24 0c 74 c9 10 	movl   $0xc010c974,0xc(%esp)
c01038c0:	c0 
c01038c1:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01038c8:	c0 
c01038c9:	c7 44 24 04 cf 00 00 	movl   $0xcf,0x4(%esp)
c01038d0:	00 
c01038d1:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01038d8:	e8 5e d4 ff ff       	call   c0100d3b <__panic>
        p->flags = 0;// 清除 flags 字段
c01038dd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01038e0:	c7 40 04 00 00 00 00 	movl   $0x0,0x4(%eax)
        set_page_ref(p, 0);// 清除引用计数
c01038e7:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01038ee:	00 
c01038ef:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01038f2:	89 04 24             	mov    %eax,(%esp)
c01038f5:	e8 19 fc ff ff       	call   c0103513 <set_page_ref>
    for (; p != base + n; p ++) {
c01038fa:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
c01038fe:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103901:	c1 e0 05             	shl    $0x5,%eax
c0103904:	89 c2                	mov    %eax,%edx
c0103906:	8b 45 08             	mov    0x8(%ebp),%eax
c0103909:	01 d0                	add    %edx,%eax
c010390b:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010390e:	0f 85 4d ff ff ff    	jne    c0103861 <default_free_pages+0x3e>
    }
    // 设置基页的属性为释放的页数
    base->property = n;
c0103914:	8b 45 08             	mov    0x8(%ebp),%eax
c0103917:	8b 55 0c             	mov    0xc(%ebp),%edx
c010391a:	89 50 08             	mov    %edx,0x8(%eax)
    SetPageProperty(base);// 设置页的有效标志
c010391d:	8b 45 08             	mov    0x8(%ebp),%eax
c0103920:	83 c0 04             	add    $0x4,%eax
c0103923:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c010392a:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c010392d:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0103930:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0103933:	0f ab 10             	bts    %edx,(%eax)
}
c0103936:	90                   	nop
c0103937:	c7 45 d4 84 3f 1a c0 	movl   $0xc01a3f84,-0x2c(%ebp)
    return listelm->next;
c010393e:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0103941:	8b 40 04             	mov    0x4(%eax),%eax
    // 遍历空闲列表，检查是否需要合并
    list_entry_t *le = list_next(&free_list);
c0103944:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list) {
c0103947:	e9 00 01 00 00       	jmp    c0103a4c <default_free_pages+0x229>
        p = le2page(le, page_link);
c010394c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010394f:	83 e8 0c             	sub    $0xc,%eax
c0103952:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0103955:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103958:	89 45 c8             	mov    %eax,-0x38(%ebp)
c010395b:	8b 45 c8             	mov    -0x38(%ebp),%eax
c010395e:	8b 40 04             	mov    0x4(%eax),%eax
        le = list_next(le);
c0103961:	89 45 f0             	mov    %eax,-0x10(%ebp)
        // 如果当前页块与释放的页块相邻，合并
        if (base + base->property == p) {
c0103964:	8b 45 08             	mov    0x8(%ebp),%eax
c0103967:	8b 40 08             	mov    0x8(%eax),%eax
c010396a:	c1 e0 05             	shl    $0x5,%eax
c010396d:	89 c2                	mov    %eax,%edx
c010396f:	8b 45 08             	mov    0x8(%ebp),%eax
c0103972:	01 d0                	add    %edx,%eax
c0103974:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0103977:	75 5d                	jne    c01039d6 <default_free_pages+0x1b3>
            base->property += p->property;// 合并当前页块
c0103979:	8b 45 08             	mov    0x8(%ebp),%eax
c010397c:	8b 50 08             	mov    0x8(%eax),%edx
c010397f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103982:	8b 40 08             	mov    0x8(%eax),%eax
c0103985:	01 c2                	add    %eax,%edx
c0103987:	8b 45 08             	mov    0x8(%ebp),%eax
c010398a:	89 50 08             	mov    %edx,0x8(%eax)
            ClearPageProperty(p);// 清除合并页的属性
c010398d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103990:	83 c0 04             	add    $0x4,%eax
c0103993:	c7 45 b8 01 00 00 00 	movl   $0x1,-0x48(%ebp)
c010399a:	89 45 b4             	mov    %eax,-0x4c(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c010399d:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c01039a0:	8b 55 b8             	mov    -0x48(%ebp),%edx
c01039a3:	0f b3 10             	btr    %edx,(%eax)
}
c01039a6:	90                   	nop
            list_del(&(p->page_link));// 从空闲列表中删除合并页
c01039a7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01039aa:	83 c0 0c             	add    $0xc,%eax
c01039ad:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    __list_del(listelm->prev, listelm->next);
c01039b0:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c01039b3:	8b 40 04             	mov    0x4(%eax),%eax
c01039b6:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c01039b9:	8b 12                	mov    (%edx),%edx
c01039bb:	89 55 c0             	mov    %edx,-0x40(%ebp)
c01039be:	89 45 bc             	mov    %eax,-0x44(%ebp)
    prev->next = next;
c01039c1:	8b 45 c0             	mov    -0x40(%ebp),%eax
c01039c4:	8b 55 bc             	mov    -0x44(%ebp),%edx
c01039c7:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c01039ca:	8b 45 bc             	mov    -0x44(%ebp),%eax
c01039cd:	8b 55 c0             	mov    -0x40(%ebp),%edx
c01039d0:	89 10                	mov    %edx,(%eax)
}
c01039d2:	90                   	nop
}
c01039d3:	90                   	nop
c01039d4:	eb 76                	jmp    c0103a4c <default_free_pages+0x229>
        }
        else if (p + p->property == base) {
c01039d6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01039d9:	8b 40 08             	mov    0x8(%eax),%eax
c01039dc:	c1 e0 05             	shl    $0x5,%eax
c01039df:	89 c2                	mov    %eax,%edx
c01039e1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01039e4:	01 d0                	add    %edx,%eax
c01039e6:	39 45 08             	cmp    %eax,0x8(%ebp)
c01039e9:	75 61                	jne    c0103a4c <default_free_pages+0x229>
            p->property += base->property;// 合并前一个页块
c01039eb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01039ee:	8b 50 08             	mov    0x8(%eax),%edx
c01039f1:	8b 45 08             	mov    0x8(%ebp),%eax
c01039f4:	8b 40 08             	mov    0x8(%eax),%eax
c01039f7:	01 c2                	add    %eax,%edx
c01039f9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01039fc:	89 50 08             	mov    %edx,0x8(%eax)
            ClearPageProperty(base);// 清除当前页的属性
c01039ff:	8b 45 08             	mov    0x8(%ebp),%eax
c0103a02:	83 c0 04             	add    $0x4,%eax
c0103a05:	c7 45 a4 01 00 00 00 	movl   $0x1,-0x5c(%ebp)
c0103a0c:	89 45 a0             	mov    %eax,-0x60(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0103a0f:	8b 45 a0             	mov    -0x60(%ebp),%eax
c0103a12:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c0103a15:	0f b3 10             	btr    %edx,(%eax)
}
c0103a18:	90                   	nop
            base = p;// 更新 base 指针
c0103a19:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103a1c:	89 45 08             	mov    %eax,0x8(%ebp)
            list_del(&(p->page_link));// 从空闲列表中删除当前页
c0103a1f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103a22:	83 c0 0c             	add    $0xc,%eax
c0103a25:	89 45 b0             	mov    %eax,-0x50(%ebp)
    __list_del(listelm->prev, listelm->next);
c0103a28:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0103a2b:	8b 40 04             	mov    0x4(%eax),%eax
c0103a2e:	8b 55 b0             	mov    -0x50(%ebp),%edx
c0103a31:	8b 12                	mov    (%edx),%edx
c0103a33:	89 55 ac             	mov    %edx,-0x54(%ebp)
c0103a36:	89 45 a8             	mov    %eax,-0x58(%ebp)
    prev->next = next;
c0103a39:	8b 45 ac             	mov    -0x54(%ebp),%eax
c0103a3c:	8b 55 a8             	mov    -0x58(%ebp),%edx
c0103a3f:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0103a42:	8b 45 a8             	mov    -0x58(%ebp),%eax
c0103a45:	8b 55 ac             	mov    -0x54(%ebp),%edx
c0103a48:	89 10                	mov    %edx,(%eax)
}
c0103a4a:	90                   	nop
}
c0103a4b:	90                   	nop
    while (le != &free_list) {
c0103a4c:	81 7d f0 84 3f 1a c0 	cmpl   $0xc01a3f84,-0x10(%ebp)
c0103a53:	0f 85 f3 fe ff ff    	jne    c010394c <default_free_pages+0x129>
        }
    }
    nr_free += n;// 更新空闲页的计数
c0103a59:	8b 15 8c 3f 1a c0    	mov    0xc01a3f8c,%edx
c0103a5f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103a62:	01 d0                	add    %edx,%eax
c0103a64:	a3 8c 3f 1a c0       	mov    %eax,0xc01a3f8c
c0103a69:	c7 45 9c 84 3f 1a c0 	movl   $0xc01a3f84,-0x64(%ebp)
    return listelm->next;
c0103a70:	8b 45 9c             	mov    -0x64(%ebp),%eax
c0103a73:	8b 40 04             	mov    0x4(%eax),%eax
    le = list_next(&free_list);
c0103a76:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list)
c0103a79:	eb 66                	jmp    c0103ae1 <default_free_pages+0x2be>
    {
        p = le2page(le, page_link);
c0103a7b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103a7e:	83 e8 0c             	sub    $0xc,%eax
c0103a81:	89 45 f4             	mov    %eax,-0xc(%ebp)
        if (base + base->property <= p)
c0103a84:	8b 45 08             	mov    0x8(%ebp),%eax
c0103a87:	8b 40 08             	mov    0x8(%eax),%eax
c0103a8a:	c1 e0 05             	shl    $0x5,%eax
c0103a8d:	89 c2                	mov    %eax,%edx
c0103a8f:	8b 45 08             	mov    0x8(%ebp),%eax
c0103a92:	01 d0                	add    %edx,%eax
c0103a94:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0103a97:	72 39                	jb     c0103ad2 <default_free_pages+0x2af>
        {
            assert(base + base->property != p);
c0103a99:	8b 45 08             	mov    0x8(%ebp),%eax
c0103a9c:	8b 40 08             	mov    0x8(%eax),%eax
c0103a9f:	c1 e0 05             	shl    $0x5,%eax
c0103aa2:	89 c2                	mov    %eax,%edx
c0103aa4:	8b 45 08             	mov    0x8(%ebp),%eax
c0103aa7:	01 d0                	add    %edx,%eax
c0103aa9:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0103aac:	75 3e                	jne    c0103aec <default_free_pages+0x2c9>
c0103aae:	c7 44 24 0c 99 c9 10 	movl   $0xc010c999,0xc(%esp)
c0103ab5:	c0 
c0103ab6:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103abd:	c0 
c0103abe:	c7 44 24 04 ef 00 00 	movl   $0xef,0x4(%esp)
c0103ac5:	00 
c0103ac6:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103acd:	e8 69 d2 ff ff       	call   c0100d3b <__panic>
c0103ad2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103ad5:	89 45 98             	mov    %eax,-0x68(%ebp)
c0103ad8:	8b 45 98             	mov    -0x68(%ebp),%eax
c0103adb:	8b 40 04             	mov    0x4(%eax),%eax
            break;
        }
        le = list_next(le);    
c0103ade:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list)
c0103ae1:	81 7d f0 84 3f 1a c0 	cmpl   $0xc01a3f84,-0x10(%ebp)
c0103ae8:	75 91                	jne    c0103a7b <default_free_pages+0x258>
c0103aea:	eb 01                	jmp    c0103aed <default_free_pages+0x2ca>
            break;
c0103aec:	90                   	nop
    }
    
    list_add_before(le, &(base->page_link));// 将释放的页块添加到空闲列表中
c0103aed:	8b 45 08             	mov    0x8(%ebp),%eax
c0103af0:	8d 50 0c             	lea    0xc(%eax),%edx
c0103af3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103af6:	89 45 94             	mov    %eax,-0x6c(%ebp)
c0103af9:	89 55 90             	mov    %edx,-0x70(%ebp)
    __list_add(elm, listelm->prev, listelm);
c0103afc:	8b 45 94             	mov    -0x6c(%ebp),%eax
c0103aff:	8b 00                	mov    (%eax),%eax
c0103b01:	8b 55 90             	mov    -0x70(%ebp),%edx
c0103b04:	89 55 8c             	mov    %edx,-0x74(%ebp)
c0103b07:	89 45 88             	mov    %eax,-0x78(%ebp)
c0103b0a:	8b 45 94             	mov    -0x6c(%ebp),%eax
c0103b0d:	89 45 84             	mov    %eax,-0x7c(%ebp)
    prev->next = next->prev = elm;
c0103b10:	8b 45 84             	mov    -0x7c(%ebp),%eax
c0103b13:	8b 55 8c             	mov    -0x74(%ebp),%edx
c0103b16:	89 10                	mov    %edx,(%eax)
c0103b18:	8b 45 84             	mov    -0x7c(%ebp),%eax
c0103b1b:	8b 10                	mov    (%eax),%edx
c0103b1d:	8b 45 88             	mov    -0x78(%ebp),%eax
c0103b20:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0103b23:	8b 45 8c             	mov    -0x74(%ebp),%eax
c0103b26:	8b 55 84             	mov    -0x7c(%ebp),%edx
c0103b29:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0103b2c:	8b 45 8c             	mov    -0x74(%ebp),%eax
c0103b2f:	8b 55 88             	mov    -0x78(%ebp),%edx
c0103b32:	89 10                	mov    %edx,(%eax)
}
c0103b34:	90                   	nop
}
c0103b35:	90                   	nop
}
c0103b36:	90                   	nop
c0103b37:	89 ec                	mov    %ebp,%esp
c0103b39:	5d                   	pop    %ebp
c0103b3a:	c3                   	ret    

c0103b3b <default_nr_free_pages>:

//用于返回当前系统中可用的空闲页的数量。
static size_t
default_nr_free_pages(void) {
c0103b3b:	55                   	push   %ebp
c0103b3c:	89 e5                	mov    %esp,%ebp
    return nr_free;// 返回当前空闲页的数量
c0103b3e:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
}
c0103b43:	5d                   	pop    %ebp
c0103b44:	c3                   	ret    

c0103b45 <basic_check>:

//basic_check 函数用于测试内存分配和释放的基本功能，
//确保在不同情况下内存管理系统的正确性，包括分配、释放、合并和引用计数等操作。
static void
basic_check(void) {
c0103b45:	55                   	push   %ebp
c0103b46:	89 e5                	mov    %esp,%ebp
c0103b48:	83 ec 48             	sub    $0x48,%esp
    struct Page *p0, *p1, *p2;
    p0 = p1 = p2 = NULL;
c0103b4b:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0103b52:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103b55:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103b58:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103b5b:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 分配三个页面
    assert((p0 = alloc_page()) != NULL);
c0103b5e:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103b65:	e8 17 16 00 00       	call   c0105181 <alloc_pages>
c0103b6a:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0103b6d:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0103b71:	75 24                	jne    c0103b97 <basic_check+0x52>
c0103b73:	c7 44 24 0c b4 c9 10 	movl   $0xc010c9b4,0xc(%esp)
c0103b7a:	c0 
c0103b7b:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103b82:	c0 
c0103b83:	c7 44 24 04 05 01 00 	movl   $0x105,0x4(%esp)
c0103b8a:	00 
c0103b8b:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103b92:	e8 a4 d1 ff ff       	call   c0100d3b <__panic>
    assert((p1 = alloc_page()) != NULL);
c0103b97:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103b9e:	e8 de 15 00 00       	call   c0105181 <alloc_pages>
c0103ba3:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103ba6:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0103baa:	75 24                	jne    c0103bd0 <basic_check+0x8b>
c0103bac:	c7 44 24 0c d0 c9 10 	movl   $0xc010c9d0,0xc(%esp)
c0103bb3:	c0 
c0103bb4:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103bbb:	c0 
c0103bbc:	c7 44 24 04 06 01 00 	movl   $0x106,0x4(%esp)
c0103bc3:	00 
c0103bc4:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103bcb:	e8 6b d1 ff ff       	call   c0100d3b <__panic>
    assert((p2 = alloc_page()) != NULL);
c0103bd0:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103bd7:	e8 a5 15 00 00       	call   c0105181 <alloc_pages>
c0103bdc:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0103bdf:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0103be3:	75 24                	jne    c0103c09 <basic_check+0xc4>
c0103be5:	c7 44 24 0c ec c9 10 	movl   $0xc010c9ec,0xc(%esp)
c0103bec:	c0 
c0103bed:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103bf4:	c0 
c0103bf5:	c7 44 24 04 07 01 00 	movl   $0x107,0x4(%esp)
c0103bfc:	00 
c0103bfd:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103c04:	e8 32 d1 ff ff       	call   c0100d3b <__panic>
     // 确保所有分配的页面是不同的
    assert(p0 != p1 && p0 != p2 && p1 != p2);
c0103c09:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103c0c:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c0103c0f:	74 10                	je     c0103c21 <basic_check+0xdc>
c0103c11:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103c14:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0103c17:	74 08                	je     c0103c21 <basic_check+0xdc>
c0103c19:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103c1c:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0103c1f:	75 24                	jne    c0103c45 <basic_check+0x100>
c0103c21:	c7 44 24 0c 08 ca 10 	movl   $0xc010ca08,0xc(%esp)
c0103c28:	c0 
c0103c29:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103c30:	c0 
c0103c31:	c7 44 24 04 09 01 00 	movl   $0x109,0x4(%esp)
c0103c38:	00 
c0103c39:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103c40:	e8 f6 d0 ff ff       	call   c0100d3b <__panic>
    // 确保页面的引用计数为 0
    assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0);
c0103c45:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103c48:	89 04 24             	mov    %eax,(%esp)
c0103c4b:	e8 b9 f8 ff ff       	call   c0103509 <page_ref>
c0103c50:	85 c0                	test   %eax,%eax
c0103c52:	75 1e                	jne    c0103c72 <basic_check+0x12d>
c0103c54:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103c57:	89 04 24             	mov    %eax,(%esp)
c0103c5a:	e8 aa f8 ff ff       	call   c0103509 <page_ref>
c0103c5f:	85 c0                	test   %eax,%eax
c0103c61:	75 0f                	jne    c0103c72 <basic_check+0x12d>
c0103c63:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103c66:	89 04 24             	mov    %eax,(%esp)
c0103c69:	e8 9b f8 ff ff       	call   c0103509 <page_ref>
c0103c6e:	85 c0                	test   %eax,%eax
c0103c70:	74 24                	je     c0103c96 <basic_check+0x151>
c0103c72:	c7 44 24 0c 2c ca 10 	movl   $0xc010ca2c,0xc(%esp)
c0103c79:	c0 
c0103c7a:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103c81:	c0 
c0103c82:	c7 44 24 04 0b 01 00 	movl   $0x10b,0x4(%esp)
c0103c89:	00 
c0103c8a:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103c91:	e8 a5 d0 ff ff       	call   c0100d3b <__panic>
    // 确保页面地址在合法范围内
    assert(page2pa(p0) < npage * PGSIZE);
c0103c96:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103c99:	89 04 24             	mov    %eax,(%esp)
c0103c9c:	e8 50 f8 ff ff       	call   c01034f1 <page2pa>
c0103ca1:	8b 15 a4 3f 1a c0    	mov    0xc01a3fa4,%edx
c0103ca7:	c1 e2 0c             	shl    $0xc,%edx
c0103caa:	39 d0                	cmp    %edx,%eax
c0103cac:	72 24                	jb     c0103cd2 <basic_check+0x18d>
c0103cae:	c7 44 24 0c 68 ca 10 	movl   $0xc010ca68,0xc(%esp)
c0103cb5:	c0 
c0103cb6:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103cbd:	c0 
c0103cbe:	c7 44 24 04 0d 01 00 	movl   $0x10d,0x4(%esp)
c0103cc5:	00 
c0103cc6:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103ccd:	e8 69 d0 ff ff       	call   c0100d3b <__panic>
    assert(page2pa(p1) < npage * PGSIZE);
c0103cd2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103cd5:	89 04 24             	mov    %eax,(%esp)
c0103cd8:	e8 14 f8 ff ff       	call   c01034f1 <page2pa>
c0103cdd:	8b 15 a4 3f 1a c0    	mov    0xc01a3fa4,%edx
c0103ce3:	c1 e2 0c             	shl    $0xc,%edx
c0103ce6:	39 d0                	cmp    %edx,%eax
c0103ce8:	72 24                	jb     c0103d0e <basic_check+0x1c9>
c0103cea:	c7 44 24 0c 85 ca 10 	movl   $0xc010ca85,0xc(%esp)
c0103cf1:	c0 
c0103cf2:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103cf9:	c0 
c0103cfa:	c7 44 24 04 0e 01 00 	movl   $0x10e,0x4(%esp)
c0103d01:	00 
c0103d02:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103d09:	e8 2d d0 ff ff       	call   c0100d3b <__panic>
    assert(page2pa(p2) < npage * PGSIZE);
c0103d0e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103d11:	89 04 24             	mov    %eax,(%esp)
c0103d14:	e8 d8 f7 ff ff       	call   c01034f1 <page2pa>
c0103d19:	8b 15 a4 3f 1a c0    	mov    0xc01a3fa4,%edx
c0103d1f:	c1 e2 0c             	shl    $0xc,%edx
c0103d22:	39 d0                	cmp    %edx,%eax
c0103d24:	72 24                	jb     c0103d4a <basic_check+0x205>
c0103d26:	c7 44 24 0c a2 ca 10 	movl   $0xc010caa2,0xc(%esp)
c0103d2d:	c0 
c0103d2e:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103d35:	c0 
c0103d36:	c7 44 24 04 0f 01 00 	movl   $0x10f,0x4(%esp)
c0103d3d:	00 
c0103d3e:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103d45:	e8 f1 cf ff ff       	call   c0100d3b <__panic>
    // 保存当前的空闲页面链表和数量
    list_entry_t free_list_store = free_list;
c0103d4a:	a1 84 3f 1a c0       	mov    0xc01a3f84,%eax
c0103d4f:	8b 15 88 3f 1a c0    	mov    0xc01a3f88,%edx
c0103d55:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0103d58:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0103d5b:	c7 45 dc 84 3f 1a c0 	movl   $0xc01a3f84,-0x24(%ebp)
    elm->prev = elm->next = elm;
c0103d62:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0103d65:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103d68:	89 50 04             	mov    %edx,0x4(%eax)
c0103d6b:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0103d6e:	8b 50 04             	mov    0x4(%eax),%edx
c0103d71:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0103d74:	89 10                	mov    %edx,(%eax)
}
c0103d76:	90                   	nop
c0103d77:	c7 45 e0 84 3f 1a c0 	movl   $0xc01a3f84,-0x20(%ebp)
    return list->next == list;
c0103d7e:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0103d81:	8b 40 04             	mov    0x4(%eax),%eax
c0103d84:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c0103d87:	0f 94 c0             	sete   %al
c0103d8a:	0f b6 c0             	movzbl %al,%eax
    list_init(&free_list);// 初始化空闲列表
    assert(list_empty(&free_list));// 确保空闲列表为空
c0103d8d:	85 c0                	test   %eax,%eax
c0103d8f:	75 24                	jne    c0103db5 <basic_check+0x270>
c0103d91:	c7 44 24 0c bf ca 10 	movl   $0xc010cabf,0xc(%esp)
c0103d98:	c0 
c0103d99:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103da0:	c0 
c0103da1:	c7 44 24 04 13 01 00 	movl   $0x113,0x4(%esp)
c0103da8:	00 
c0103da9:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103db0:	e8 86 cf ff ff       	call   c0100d3b <__panic>

    unsigned int nr_free_store = nr_free;// 保存当前空闲页数量
c0103db5:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c0103dba:	89 45 e8             	mov    %eax,-0x18(%ebp)
    nr_free = 0;// 将空闲页数量设为 0
c0103dbd:	c7 05 8c 3f 1a c0 00 	movl   $0x0,0xc01a3f8c
c0103dc4:	00 00 00 
    // 请求分配页面，但当前没有空闲页面
    assert(alloc_page() == NULL);
c0103dc7:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103dce:	e8 ae 13 00 00       	call   c0105181 <alloc_pages>
c0103dd3:	85 c0                	test   %eax,%eax
c0103dd5:	74 24                	je     c0103dfb <basic_check+0x2b6>
c0103dd7:	c7 44 24 0c d6 ca 10 	movl   $0xc010cad6,0xc(%esp)
c0103dde:	c0 
c0103ddf:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103de6:	c0 
c0103de7:	c7 44 24 04 18 01 00 	movl   $0x118,0x4(%esp)
c0103dee:	00 
c0103def:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103df6:	e8 40 cf ff ff       	call   c0100d3b <__panic>
    // 释放之前分配的页面
    free_page(p0);
c0103dfb:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103e02:	00 
c0103e03:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103e06:	89 04 24             	mov    %eax,(%esp)
c0103e09:	e8 e0 13 00 00       	call   c01051ee <free_pages>
    free_page(p1);
c0103e0e:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103e15:	00 
c0103e16:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103e19:	89 04 24             	mov    %eax,(%esp)
c0103e1c:	e8 cd 13 00 00       	call   c01051ee <free_pages>
    free_page(p2);
c0103e21:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103e28:	00 
c0103e29:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103e2c:	89 04 24             	mov    %eax,(%esp)
c0103e2f:	e8 ba 13 00 00       	call   c01051ee <free_pages>
    assert(nr_free == 3);// 确保释放后空闲页数量为 3
c0103e34:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c0103e39:	83 f8 03             	cmp    $0x3,%eax
c0103e3c:	74 24                	je     c0103e62 <basic_check+0x31d>
c0103e3e:	c7 44 24 0c eb ca 10 	movl   $0xc010caeb,0xc(%esp)
c0103e45:	c0 
c0103e46:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103e4d:	c0 
c0103e4e:	c7 44 24 04 1d 01 00 	movl   $0x11d,0x4(%esp)
c0103e55:	00 
c0103e56:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103e5d:	e8 d9 ce ff ff       	call   c0100d3b <__panic>
    // 再次分配三个页面
    assert((p0 = alloc_page()) != NULL);
c0103e62:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103e69:	e8 13 13 00 00       	call   c0105181 <alloc_pages>
c0103e6e:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0103e71:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0103e75:	75 24                	jne    c0103e9b <basic_check+0x356>
c0103e77:	c7 44 24 0c b4 c9 10 	movl   $0xc010c9b4,0xc(%esp)
c0103e7e:	c0 
c0103e7f:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103e86:	c0 
c0103e87:	c7 44 24 04 1f 01 00 	movl   $0x11f,0x4(%esp)
c0103e8e:	00 
c0103e8f:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103e96:	e8 a0 ce ff ff       	call   c0100d3b <__panic>
    assert((p1 = alloc_page()) != NULL);
c0103e9b:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103ea2:	e8 da 12 00 00       	call   c0105181 <alloc_pages>
c0103ea7:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103eaa:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0103eae:	75 24                	jne    c0103ed4 <basic_check+0x38f>
c0103eb0:	c7 44 24 0c d0 c9 10 	movl   $0xc010c9d0,0xc(%esp)
c0103eb7:	c0 
c0103eb8:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103ebf:	c0 
c0103ec0:	c7 44 24 04 20 01 00 	movl   $0x120,0x4(%esp)
c0103ec7:	00 
c0103ec8:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103ecf:	e8 67 ce ff ff       	call   c0100d3b <__panic>
    assert((p2 = alloc_page()) != NULL);
c0103ed4:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103edb:	e8 a1 12 00 00       	call   c0105181 <alloc_pages>
c0103ee0:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0103ee3:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0103ee7:	75 24                	jne    c0103f0d <basic_check+0x3c8>
c0103ee9:	c7 44 24 0c ec c9 10 	movl   $0xc010c9ec,0xc(%esp)
c0103ef0:	c0 
c0103ef1:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103ef8:	c0 
c0103ef9:	c7 44 24 04 21 01 00 	movl   $0x121,0x4(%esp)
c0103f00:	00 
c0103f01:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103f08:	e8 2e ce ff ff       	call   c0100d3b <__panic>
    // 测试空闲页面是否不足
    assert(alloc_page() == NULL);
c0103f0d:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103f14:	e8 68 12 00 00       	call   c0105181 <alloc_pages>
c0103f19:	85 c0                	test   %eax,%eax
c0103f1b:	74 24                	je     c0103f41 <basic_check+0x3fc>
c0103f1d:	c7 44 24 0c d6 ca 10 	movl   $0xc010cad6,0xc(%esp)
c0103f24:	c0 
c0103f25:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103f2c:	c0 
c0103f2d:	c7 44 24 04 23 01 00 	movl   $0x123,0x4(%esp)
c0103f34:	00 
c0103f35:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103f3c:	e8 fa cd ff ff       	call   c0100d3b <__panic>
    // 释放 p0，并检查空闲列表
    free_page(p0);
c0103f41:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103f48:	00 
c0103f49:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103f4c:	89 04 24             	mov    %eax,(%esp)
c0103f4f:	e8 9a 12 00 00       	call   c01051ee <free_pages>
c0103f54:	c7 45 d8 84 3f 1a c0 	movl   $0xc01a3f84,-0x28(%ebp)
c0103f5b:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0103f5e:	8b 40 04             	mov    0x4(%eax),%eax
c0103f61:	39 45 d8             	cmp    %eax,-0x28(%ebp)
c0103f64:	0f 94 c0             	sete   %al
c0103f67:	0f b6 c0             	movzbl %al,%eax
    assert(!list_empty(&free_list));// 确保空闲列表不为空
c0103f6a:	85 c0                	test   %eax,%eax
c0103f6c:	74 24                	je     c0103f92 <basic_check+0x44d>
c0103f6e:	c7 44 24 0c f8 ca 10 	movl   $0xc010caf8,0xc(%esp)
c0103f75:	c0 
c0103f76:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103f7d:	c0 
c0103f7e:	c7 44 24 04 26 01 00 	movl   $0x126,0x4(%esp)
c0103f85:	00 
c0103f86:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103f8d:	e8 a9 cd ff ff       	call   c0100d3b <__panic>

    struct Page *p;
    // 重新分配 p0，确保取回的是相同的页面
    assert((p = alloc_page()) == p0);
c0103f92:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103f99:	e8 e3 11 00 00       	call   c0105181 <alloc_pages>
c0103f9e:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0103fa1:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0103fa4:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0103fa7:	74 24                	je     c0103fcd <basic_check+0x488>
c0103fa9:	c7 44 24 0c 10 cb 10 	movl   $0xc010cb10,0xc(%esp)
c0103fb0:	c0 
c0103fb1:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103fb8:	c0 
c0103fb9:	c7 44 24 04 2a 01 00 	movl   $0x12a,0x4(%esp)
c0103fc0:	00 
c0103fc1:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103fc8:	e8 6e cd ff ff       	call   c0100d3b <__panic>
    assert(alloc_page() == NULL);// 确保没有更多的页面可分配
c0103fcd:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103fd4:	e8 a8 11 00 00       	call   c0105181 <alloc_pages>
c0103fd9:	85 c0                	test   %eax,%eax
c0103fdb:	74 24                	je     c0104001 <basic_check+0x4bc>
c0103fdd:	c7 44 24 0c d6 ca 10 	movl   $0xc010cad6,0xc(%esp)
c0103fe4:	c0 
c0103fe5:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0103fec:	c0 
c0103fed:	c7 44 24 04 2b 01 00 	movl   $0x12b,0x4(%esp)
c0103ff4:	00 
c0103ff5:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0103ffc:	e8 3a cd ff ff       	call   c0100d3b <__panic>

    assert(nr_free == 0);// 确保当前空闲页面数量为 0
c0104001:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c0104006:	85 c0                	test   %eax,%eax
c0104008:	74 24                	je     c010402e <basic_check+0x4e9>
c010400a:	c7 44 24 0c 29 cb 10 	movl   $0xc010cb29,0xc(%esp)
c0104011:	c0 
c0104012:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104019:	c0 
c010401a:	c7 44 24 04 2d 01 00 	movl   $0x12d,0x4(%esp)
c0104021:	00 
c0104022:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104029:	e8 0d cd ff ff       	call   c0100d3b <__panic>
    // 恢复之前的空闲页面链表和数量
    free_list = free_list_store;
c010402e:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0104031:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0104034:	a3 84 3f 1a c0       	mov    %eax,0xc01a3f84
c0104039:	89 15 88 3f 1a c0    	mov    %edx,0xc01a3f88
    nr_free = nr_free_store;
c010403f:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104042:	a3 8c 3f 1a c0       	mov    %eax,0xc01a3f8c
    // 释放最后的页面
    free_page(p);
c0104047:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010404e:	00 
c010404f:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0104052:	89 04 24             	mov    %eax,(%esp)
c0104055:	e8 94 11 00 00       	call   c01051ee <free_pages>
    free_page(p1);
c010405a:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0104061:	00 
c0104062:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104065:	89 04 24             	mov    %eax,(%esp)
c0104068:	e8 81 11 00 00       	call   c01051ee <free_pages>
    free_page(p2);
c010406d:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0104074:	00 
c0104075:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104078:	89 04 24             	mov    %eax,(%esp)
c010407b:	e8 6e 11 00 00       	call   c01051ee <free_pages>
}
c0104080:	90                   	nop
c0104081:	89 ec                	mov    %ebp,%esp
c0104083:	5d                   	pop    %ebp
c0104084:	c3                   	ret    

c0104085 <default_check>:

// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) 
// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions!
static void
default_check(void) {
c0104085:	55                   	push   %ebp
c0104086:	89 e5                	mov    %esp,%ebp
c0104088:	81 ec 98 00 00 00    	sub    $0x98,%esp
    int count = 0, total = 0;
c010408e:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0104095:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    list_entry_t *le = &free_list;
c010409c:	c7 45 ec 84 3f 1a c0 	movl   $0xc01a3f84,-0x14(%ebp)
    // 遍历空闲列表，计算空闲页面的数量和总属性值
    while ((le = list_next(le)) != &free_list) {
c01040a3:	eb 6a                	jmp    c010410f <default_check+0x8a>
        struct Page *p = le2page(le, page_link);
c01040a5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01040a8:	83 e8 0c             	sub    $0xc,%eax
c01040ab:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        assert(PageProperty(p));// 确保每个页面的属性是有效的
c01040ae:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01040b1:	83 c0 04             	add    $0x4,%eax
c01040b4:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c01040bb:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01040be:	8b 45 cc             	mov    -0x34(%ebp),%eax
c01040c1:	8b 55 d0             	mov    -0x30(%ebp),%edx
c01040c4:	0f a3 10             	bt     %edx,(%eax)
c01040c7:	19 c0                	sbb    %eax,%eax
c01040c9:	89 45 c8             	mov    %eax,-0x38(%ebp)
    return oldbit != 0;
c01040cc:	83 7d c8 00          	cmpl   $0x0,-0x38(%ebp)
c01040d0:	0f 95 c0             	setne  %al
c01040d3:	0f b6 c0             	movzbl %al,%eax
c01040d6:	85 c0                	test   %eax,%eax
c01040d8:	75 24                	jne    c01040fe <default_check+0x79>
c01040da:	c7 44 24 0c 36 cb 10 	movl   $0xc010cb36,0xc(%esp)
c01040e1:	c0 
c01040e2:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01040e9:	c0 
c01040ea:	c7 44 24 04 40 01 00 	movl   $0x140,0x4(%esp)
c01040f1:	00 
c01040f2:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01040f9:	e8 3d cc ff ff       	call   c0100d3b <__panic>
        count ++, total += p->property;// 累加页面属性
c01040fe:	ff 45 f4             	incl   -0xc(%ebp)
c0104101:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0104104:	8b 50 08             	mov    0x8(%eax),%edx
c0104107:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010410a:	01 d0                	add    %edx,%eax
c010410c:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010410f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104112:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    return listelm->next;
c0104115:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0104118:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c010411b:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010411e:	81 7d ec 84 3f 1a c0 	cmpl   $0xc01a3f84,-0x14(%ebp)
c0104125:	0f 85 7a ff ff ff    	jne    c01040a5 <default_check+0x20>
    }
    // 确保总属性值与空闲页面数量匹配
    assert(total == nr_free_pages());
c010412b:	e8 f3 10 00 00       	call   c0105223 <nr_free_pages>
c0104130:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0104133:	39 d0                	cmp    %edx,%eax
c0104135:	74 24                	je     c010415b <default_check+0xd6>
c0104137:	c7 44 24 0c 46 cb 10 	movl   $0xc010cb46,0xc(%esp)
c010413e:	c0 
c010413f:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104146:	c0 
c0104147:	c7 44 24 04 44 01 00 	movl   $0x144,0x4(%esp)
c010414e:	00 
c010414f:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104156:	e8 e0 cb ff ff       	call   c0100d3b <__panic>
    // 调用 basic_check 以验证基本的内存管理功能
    basic_check();
c010415b:	e8 e5 f9 ff ff       	call   c0103b45 <basic_check>
    // 分配 5 个页面
    struct Page *p0 = alloc_pages(5), *p1, *p2;
c0104160:	c7 04 24 05 00 00 00 	movl   $0x5,(%esp)
c0104167:	e8 15 10 00 00       	call   c0105181 <alloc_pages>
c010416c:	89 45 e8             	mov    %eax,-0x18(%ebp)
    assert(p0 != NULL);// 确保成功分配
c010416f:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0104173:	75 24                	jne    c0104199 <default_check+0x114>
c0104175:	c7 44 24 0c 5f cb 10 	movl   $0xc010cb5f,0xc(%esp)
c010417c:	c0 
c010417d:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104184:	c0 
c0104185:	c7 44 24 04 49 01 00 	movl   $0x149,0x4(%esp)
c010418c:	00 
c010418d:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104194:	e8 a2 cb ff ff       	call   c0100d3b <__panic>
    assert(!PageProperty(p0));// 确保分配的页面不带属性
c0104199:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010419c:	83 c0 04             	add    $0x4,%eax
c010419f:	c7 45 c0 01 00 00 00 	movl   $0x1,-0x40(%ebp)
c01041a6:	89 45 bc             	mov    %eax,-0x44(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01041a9:	8b 45 bc             	mov    -0x44(%ebp),%eax
c01041ac:	8b 55 c0             	mov    -0x40(%ebp),%edx
c01041af:	0f a3 10             	bt     %edx,(%eax)
c01041b2:	19 c0                	sbb    %eax,%eax
c01041b4:	89 45 b8             	mov    %eax,-0x48(%ebp)
    return oldbit != 0;
c01041b7:	83 7d b8 00          	cmpl   $0x0,-0x48(%ebp)
c01041bb:	0f 95 c0             	setne  %al
c01041be:	0f b6 c0             	movzbl %al,%eax
c01041c1:	85 c0                	test   %eax,%eax
c01041c3:	74 24                	je     c01041e9 <default_check+0x164>
c01041c5:	c7 44 24 0c 6a cb 10 	movl   $0xc010cb6a,0xc(%esp)
c01041cc:	c0 
c01041cd:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01041d4:	c0 
c01041d5:	c7 44 24 04 4a 01 00 	movl   $0x14a,0x4(%esp)
c01041dc:	00 
c01041dd:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01041e4:	e8 52 cb ff ff       	call   c0100d3b <__panic>
     // 初始化并检查空闲列表
    list_entry_t free_list_store = free_list;
c01041e9:	a1 84 3f 1a c0       	mov    0xc01a3f84,%eax
c01041ee:	8b 15 88 3f 1a c0    	mov    0xc01a3f88,%edx
c01041f4:	89 45 80             	mov    %eax,-0x80(%ebp)
c01041f7:	89 55 84             	mov    %edx,-0x7c(%ebp)
c01041fa:	c7 45 b0 84 3f 1a c0 	movl   $0xc01a3f84,-0x50(%ebp)
    elm->prev = elm->next = elm;
c0104201:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0104204:	8b 55 b0             	mov    -0x50(%ebp),%edx
c0104207:	89 50 04             	mov    %edx,0x4(%eax)
c010420a:	8b 45 b0             	mov    -0x50(%ebp),%eax
c010420d:	8b 50 04             	mov    0x4(%eax),%edx
c0104210:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0104213:	89 10                	mov    %edx,(%eax)
}
c0104215:	90                   	nop
c0104216:	c7 45 b4 84 3f 1a c0 	movl   $0xc01a3f84,-0x4c(%ebp)
    return list->next == list;
c010421d:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0104220:	8b 40 04             	mov    0x4(%eax),%eax
c0104223:	39 45 b4             	cmp    %eax,-0x4c(%ebp)
c0104226:	0f 94 c0             	sete   %al
c0104229:	0f b6 c0             	movzbl %al,%eax
    list_init(&free_list);
    assert(list_empty(&free_list));// 确保空闲列表为空
c010422c:	85 c0                	test   %eax,%eax
c010422e:	75 24                	jne    c0104254 <default_check+0x1cf>
c0104230:	c7 44 24 0c bf ca 10 	movl   $0xc010cabf,0xc(%esp)
c0104237:	c0 
c0104238:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c010423f:	c0 
c0104240:	c7 44 24 04 4e 01 00 	movl   $0x14e,0x4(%esp)
c0104247:	00 
c0104248:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c010424f:	e8 e7 ca ff ff       	call   c0100d3b <__panic>
    assert(alloc_page() == NULL);// 确保没有页面可分配
c0104254:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c010425b:	e8 21 0f 00 00       	call   c0105181 <alloc_pages>
c0104260:	85 c0                	test   %eax,%eax
c0104262:	74 24                	je     c0104288 <default_check+0x203>
c0104264:	c7 44 24 0c d6 ca 10 	movl   $0xc010cad6,0xc(%esp)
c010426b:	c0 
c010426c:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104273:	c0 
c0104274:	c7 44 24 04 4f 01 00 	movl   $0x14f,0x4(%esp)
c010427b:	00 
c010427c:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104283:	e8 b3 ca ff ff       	call   c0100d3b <__panic>

    unsigned int nr_free_store = nr_free;// 保存当前空闲页数
c0104288:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c010428d:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    nr_free = 0;// 将空闲页数设为 0
c0104290:	c7 05 8c 3f 1a c0 00 	movl   $0x0,0xc01a3f8c
c0104297:	00 00 00 
    // 释放 3 个页面并确保分配页面时没有足够的空闲页
    free_pages(p0 + 2, 3);
c010429a:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010429d:	83 c0 40             	add    $0x40,%eax
c01042a0:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%esp)
c01042a7:	00 
c01042a8:	89 04 24             	mov    %eax,(%esp)
c01042ab:	e8 3e 0f 00 00       	call   c01051ee <free_pages>
    assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面
c01042b0:	c7 04 24 04 00 00 00 	movl   $0x4,(%esp)
c01042b7:	e8 c5 0e 00 00       	call   c0105181 <alloc_pages>
c01042bc:	85 c0                	test   %eax,%eax
c01042be:	74 24                	je     c01042e4 <default_check+0x25f>
c01042c0:	c7 44 24 0c 7c cb 10 	movl   $0xc010cb7c,0xc(%esp)
c01042c7:	c0 
c01042c8:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01042cf:	c0 
c01042d0:	c7 44 24 04 55 01 00 	movl   $0x155,0x4(%esp)
c01042d7:	00 
c01042d8:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01042df:	e8 57 ca ff ff       	call   c0100d3b <__panic>
    assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性
c01042e4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01042e7:	83 c0 40             	add    $0x40,%eax
c01042ea:	83 c0 04             	add    $0x4,%eax
c01042ed:	c7 45 ac 01 00 00 00 	movl   $0x1,-0x54(%ebp)
c01042f4:	89 45 a8             	mov    %eax,-0x58(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01042f7:	8b 45 a8             	mov    -0x58(%ebp),%eax
c01042fa:	8b 55 ac             	mov    -0x54(%ebp),%edx
c01042fd:	0f a3 10             	bt     %edx,(%eax)
c0104300:	19 c0                	sbb    %eax,%eax
c0104302:	89 45 a4             	mov    %eax,-0x5c(%ebp)
    return oldbit != 0;
c0104305:	83 7d a4 00          	cmpl   $0x0,-0x5c(%ebp)
c0104309:	0f 95 c0             	setne  %al
c010430c:	0f b6 c0             	movzbl %al,%eax
c010430f:	85 c0                	test   %eax,%eax
c0104311:	74 0e                	je     c0104321 <default_check+0x29c>
c0104313:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104316:	83 c0 40             	add    $0x40,%eax
c0104319:	8b 40 08             	mov    0x8(%eax),%eax
c010431c:	83 f8 03             	cmp    $0x3,%eax
c010431f:	74 24                	je     c0104345 <default_check+0x2c0>
c0104321:	c7 44 24 0c 94 cb 10 	movl   $0xc010cb94,0xc(%esp)
c0104328:	c0 
c0104329:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104330:	c0 
c0104331:	c7 44 24 04 56 01 00 	movl   $0x156,0x4(%esp)
c0104338:	00 
c0104339:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104340:	e8 f6 c9 ff ff       	call   c0100d3b <__panic>
    assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面
c0104345:	c7 04 24 03 00 00 00 	movl   $0x3,(%esp)
c010434c:	e8 30 0e 00 00       	call   c0105181 <alloc_pages>
c0104351:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0104354:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c0104358:	75 24                	jne    c010437e <default_check+0x2f9>
c010435a:	c7 44 24 0c c0 cb 10 	movl   $0xc010cbc0,0xc(%esp)
c0104361:	c0 
c0104362:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104369:	c0 
c010436a:	c7 44 24 04 57 01 00 	movl   $0x157,0x4(%esp)
c0104371:	00 
c0104372:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104379:	e8 bd c9 ff ff       	call   c0100d3b <__panic>
    assert(alloc_page() == NULL);// 确保没有页面可分配
c010437e:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0104385:	e8 f7 0d 00 00       	call   c0105181 <alloc_pages>
c010438a:	85 c0                	test   %eax,%eax
c010438c:	74 24                	je     c01043b2 <default_check+0x32d>
c010438e:	c7 44 24 0c d6 ca 10 	movl   $0xc010cad6,0xc(%esp)
c0104395:	c0 
c0104396:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c010439d:	c0 
c010439e:	c7 44 24 04 58 01 00 	movl   $0x158,0x4(%esp)
c01043a5:	00 
c01043a6:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01043ad:	e8 89 c9 ff ff       	call   c0100d3b <__panic>
    assert(p0 + 2 == p1);// 确保分配的页面是释放的页面
c01043b2:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01043b5:	83 c0 40             	add    $0x40,%eax
c01043b8:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c01043bb:	74 24                	je     c01043e1 <default_check+0x35c>
c01043bd:	c7 44 24 0c de cb 10 	movl   $0xc010cbde,0xc(%esp)
c01043c4:	c0 
c01043c5:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01043cc:	c0 
c01043cd:	c7 44 24 04 59 01 00 	movl   $0x159,0x4(%esp)
c01043d4:	00 
c01043d5:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01043dc:	e8 5a c9 ff ff       	call   c0100d3b <__panic>

    p2 = p0 + 1;// 设置 p2 为 p0 的下一个页面
c01043e1:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01043e4:	83 c0 20             	add    $0x20,%eax
c01043e7:	89 45 dc             	mov    %eax,-0x24(%ebp)
    free_page(p0);// 释放 p0 页面
c01043ea:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01043f1:	00 
c01043f2:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01043f5:	89 04 24             	mov    %eax,(%esp)
c01043f8:	e8 f1 0d 00 00       	call   c01051ee <free_pages>
    free_pages(p1, 3);// 释放 p1 指向的页面
c01043fd:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%esp)
c0104404:	00 
c0104405:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0104408:	89 04 24             	mov    %eax,(%esp)
c010440b:	e8 de 0d 00 00       	call   c01051ee <free_pages>
    assert(PageProperty(p0) && p0->property == 1);// 检查 p0 属性
c0104410:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104413:	83 c0 04             	add    $0x4,%eax
c0104416:	c7 45 a0 01 00 00 00 	movl   $0x1,-0x60(%ebp)
c010441d:	89 45 9c             	mov    %eax,-0x64(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0104420:	8b 45 9c             	mov    -0x64(%ebp),%eax
c0104423:	8b 55 a0             	mov    -0x60(%ebp),%edx
c0104426:	0f a3 10             	bt     %edx,(%eax)
c0104429:	19 c0                	sbb    %eax,%eax
c010442b:	89 45 98             	mov    %eax,-0x68(%ebp)
    return oldbit != 0;
c010442e:	83 7d 98 00          	cmpl   $0x0,-0x68(%ebp)
c0104432:	0f 95 c0             	setne  %al
c0104435:	0f b6 c0             	movzbl %al,%eax
c0104438:	85 c0                	test   %eax,%eax
c010443a:	74 0b                	je     c0104447 <default_check+0x3c2>
c010443c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010443f:	8b 40 08             	mov    0x8(%eax),%eax
c0104442:	83 f8 01             	cmp    $0x1,%eax
c0104445:	74 24                	je     c010446b <default_check+0x3e6>
c0104447:	c7 44 24 0c ec cb 10 	movl   $0xc010cbec,0xc(%esp)
c010444e:	c0 
c010444f:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104456:	c0 
c0104457:	c7 44 24 04 5e 01 00 	movl   $0x15e,0x4(%esp)
c010445e:	00 
c010445f:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104466:	e8 d0 c8 ff ff       	call   c0100d3b <__panic>
    assert(PageProperty(p1) && p1->property == 3);// 检查 p1 属性
c010446b:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010446e:	83 c0 04             	add    $0x4,%eax
c0104471:	c7 45 94 01 00 00 00 	movl   $0x1,-0x6c(%ebp)
c0104478:	89 45 90             	mov    %eax,-0x70(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c010447b:	8b 45 90             	mov    -0x70(%ebp),%eax
c010447e:	8b 55 94             	mov    -0x6c(%ebp),%edx
c0104481:	0f a3 10             	bt     %edx,(%eax)
c0104484:	19 c0                	sbb    %eax,%eax
c0104486:	89 45 8c             	mov    %eax,-0x74(%ebp)
    return oldbit != 0;
c0104489:	83 7d 8c 00          	cmpl   $0x0,-0x74(%ebp)
c010448d:	0f 95 c0             	setne  %al
c0104490:	0f b6 c0             	movzbl %al,%eax
c0104493:	85 c0                	test   %eax,%eax
c0104495:	74 0b                	je     c01044a2 <default_check+0x41d>
c0104497:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010449a:	8b 40 08             	mov    0x8(%eax),%eax
c010449d:	83 f8 03             	cmp    $0x3,%eax
c01044a0:	74 24                	je     c01044c6 <default_check+0x441>
c01044a2:	c7 44 24 0c 14 cc 10 	movl   $0xc010cc14,0xc(%esp)
c01044a9:	c0 
c01044aa:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01044b1:	c0 
c01044b2:	c7 44 24 04 5f 01 00 	movl   $0x15f,0x4(%esp)
c01044b9:	00 
c01044ba:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01044c1:	e8 75 c8 ff ff       	call   c0100d3b <__panic>
    // 确保重分配的页面是之前释放的页面
    assert((p0 = alloc_page()) == p2 - 1);
c01044c6:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01044cd:	e8 af 0c 00 00       	call   c0105181 <alloc_pages>
c01044d2:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01044d5:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01044d8:	83 e8 20             	sub    $0x20,%eax
c01044db:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c01044de:	74 24                	je     c0104504 <default_check+0x47f>
c01044e0:	c7 44 24 0c 3a cc 10 	movl   $0xc010cc3a,0xc(%esp)
c01044e7:	c0 
c01044e8:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01044ef:	c0 
c01044f0:	c7 44 24 04 61 01 00 	movl   $0x161,0x4(%esp)
c01044f7:	00 
c01044f8:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01044ff:	e8 37 c8 ff ff       	call   c0100d3b <__panic>
    free_page(p0);// 释放分配的页面
c0104504:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010450b:	00 
c010450c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010450f:	89 04 24             	mov    %eax,(%esp)
c0104512:	e8 d7 0c 00 00       	call   c01051ee <free_pages>
    assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查
c0104517:	c7 04 24 02 00 00 00 	movl   $0x2,(%esp)
c010451e:	e8 5e 0c 00 00       	call   c0105181 <alloc_pages>
c0104523:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0104526:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0104529:	83 c0 20             	add    $0x20,%eax
c010452c:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c010452f:	74 24                	je     c0104555 <default_check+0x4d0>
c0104531:	c7 44 24 0c 58 cc 10 	movl   $0xc010cc58,0xc(%esp)
c0104538:	c0 
c0104539:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104540:	c0 
c0104541:	c7 44 24 04 63 01 00 	movl   $0x163,0x4(%esp)
c0104548:	00 
c0104549:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104550:	e8 e6 c7 ff ff       	call   c0100d3b <__panic>
    // 释放页面并检查空闲状态
    free_pages(p0, 2);
c0104555:	c7 44 24 04 02 00 00 	movl   $0x2,0x4(%esp)
c010455c:	00 
c010455d:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104560:	89 04 24             	mov    %eax,(%esp)
c0104563:	e8 86 0c 00 00       	call   c01051ee <free_pages>
    free_page(p2);
c0104568:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010456f:	00 
c0104570:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0104573:	89 04 24             	mov    %eax,(%esp)
c0104576:	e8 73 0c 00 00       	call   c01051ee <free_pages>
    // 再次分配 5 个页面
    assert((p0 = alloc_pages(5)) != NULL);
c010457b:	c7 04 24 05 00 00 00 	movl   $0x5,(%esp)
c0104582:	e8 fa 0b 00 00       	call   c0105181 <alloc_pages>
c0104587:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010458a:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010458e:	75 24                	jne    c01045b4 <default_check+0x52f>
c0104590:	c7 44 24 0c 78 cc 10 	movl   $0xc010cc78,0xc(%esp)
c0104597:	c0 
c0104598:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c010459f:	c0 
c01045a0:	c7 44 24 04 68 01 00 	movl   $0x168,0x4(%esp)
c01045a7:	00 
c01045a8:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01045af:	e8 87 c7 ff ff       	call   c0100d3b <__panic>
    assert(alloc_page() == NULL);// 确保没有额外页面可分配
c01045b4:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01045bb:	e8 c1 0b 00 00       	call   c0105181 <alloc_pages>
c01045c0:	85 c0                	test   %eax,%eax
c01045c2:	74 24                	je     c01045e8 <default_check+0x563>
c01045c4:	c7 44 24 0c d6 ca 10 	movl   $0xc010cad6,0xc(%esp)
c01045cb:	c0 
c01045cc:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01045d3:	c0 
c01045d4:	c7 44 24 04 69 01 00 	movl   $0x169,0x4(%esp)
c01045db:	00 
c01045dc:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01045e3:	e8 53 c7 ff ff       	call   c0100d3b <__panic>

    assert(nr_free == 0);// 确保空闲页数为 0
c01045e8:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c01045ed:	85 c0                	test   %eax,%eax
c01045ef:	74 24                	je     c0104615 <default_check+0x590>
c01045f1:	c7 44 24 0c 29 cb 10 	movl   $0xc010cb29,0xc(%esp)
c01045f8:	c0 
c01045f9:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104600:	c0 
c0104601:	c7 44 24 04 6b 01 00 	movl   $0x16b,0x4(%esp)
c0104608:	00 
c0104609:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c0104610:	e8 26 c7 ff ff       	call   c0100d3b <__panic>
    nr_free = nr_free_store;// 恢复空闲页数
c0104615:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0104618:	a3 8c 3f 1a c0       	mov    %eax,0xc01a3f8c
    // 恢复空闲列表状态
    free_list = free_list_store;
c010461d:	8b 45 80             	mov    -0x80(%ebp),%eax
c0104620:	8b 55 84             	mov    -0x7c(%ebp),%edx
c0104623:	a3 84 3f 1a c0       	mov    %eax,0xc01a3f84
c0104628:	89 15 88 3f 1a c0    	mov    %edx,0xc01a3f88
    free_pages(p0, 5);// 释放所有分配的页面
c010462e:	c7 44 24 04 05 00 00 	movl   $0x5,0x4(%esp)
c0104635:	00 
c0104636:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104639:	89 04 24             	mov    %eax,(%esp)
c010463c:	e8 ad 0b 00 00       	call   c01051ee <free_pages>
    // 验证空闲列表的一致性
    le = &free_list;
c0104641:	c7 45 ec 84 3f 1a c0 	movl   $0xc01a3f84,-0x14(%ebp)
    while ((le = list_next(le)) != &free_list) {
c0104648:	eb 1c                	jmp    c0104666 <default_check+0x5e1>
        struct Page *p = le2page(le, page_link);
c010464a:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010464d:	83 e8 0c             	sub    $0xc,%eax
c0104650:	89 45 d8             	mov    %eax,-0x28(%ebp)
        count --, total -= p->property;
c0104653:	ff 4d f4             	decl   -0xc(%ebp)
c0104656:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0104659:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010465c:	8b 48 08             	mov    0x8(%eax),%ecx
c010465f:	89 d0                	mov    %edx,%eax
c0104661:	29 c8                	sub    %ecx,%eax
c0104663:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0104666:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104669:	89 45 88             	mov    %eax,-0x78(%ebp)
    return listelm->next;
c010466c:	8b 45 88             	mov    -0x78(%ebp),%eax
c010466f:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c0104672:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0104675:	81 7d ec 84 3f 1a c0 	cmpl   $0xc01a3f84,-0x14(%ebp)
c010467c:	75 cc                	jne    c010464a <default_check+0x5c5>
    }
    assert(count == 0);// 确保所有页面都已处理
c010467e:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104682:	74 24                	je     c01046a8 <default_check+0x623>
c0104684:	c7 44 24 0c 96 cc 10 	movl   $0xc010cc96,0xc(%esp)
c010468b:	c0 
c010468c:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c0104693:	c0 
c0104694:	c7 44 24 04 76 01 00 	movl   $0x176,0x4(%esp)
c010469b:	00 
c010469c:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01046a3:	e8 93 c6 ff ff       	call   c0100d3b <__panic>
    assert(total == 0);// 确保总属性值为 0
c01046a8:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01046ac:	74 24                	je     c01046d2 <default_check+0x64d>
c01046ae:	c7 44 24 0c a1 cc 10 	movl   $0xc010cca1,0xc(%esp)
c01046b5:	c0 
c01046b6:	c7 44 24 08 36 c9 10 	movl   $0xc010c936,0x8(%esp)
c01046bd:	c0 
c01046be:	c7 44 24 04 77 01 00 	movl   $0x177,0x4(%esp)
c01046c5:	00 
c01046c6:	c7 04 24 4b c9 10 c0 	movl   $0xc010c94b,(%esp)
c01046cd:	e8 69 c6 ff ff       	call   c0100d3b <__panic>
}
c01046d2:	90                   	nop
c01046d3:	89 ec                	mov    %ebp,%esp
c01046d5:	5d                   	pop    %ebp
c01046d6:	c3                   	ret    

c01046d7 <__intr_save>:
__intr_save(void) {
c01046d7:	55                   	push   %ebp
c01046d8:	89 e5                	mov    %esp,%ebp
c01046da:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c01046dd:	9c                   	pushf  
c01046de:	58                   	pop    %eax
c01046df:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c01046e2:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c01046e5:	25 00 02 00 00       	and    $0x200,%eax
c01046ea:	85 c0                	test   %eax,%eax
c01046ec:	74 0c                	je     c01046fa <__intr_save+0x23>
        intr_disable();
c01046ee:	e8 fe d8 ff ff       	call   c0101ff1 <intr_disable>
        return 1;
c01046f3:	b8 01 00 00 00       	mov    $0x1,%eax
c01046f8:	eb 05                	jmp    c01046ff <__intr_save+0x28>
    return 0;
c01046fa:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01046ff:	89 ec                	mov    %ebp,%esp
c0104701:	5d                   	pop    %ebp
c0104702:	c3                   	ret    

c0104703 <__intr_restore>:
__intr_restore(bool flag) {
c0104703:	55                   	push   %ebp
c0104704:	89 e5                	mov    %esp,%ebp
c0104706:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c0104709:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c010470d:	74 05                	je     c0104714 <__intr_restore+0x11>
        intr_enable();
c010470f:	e8 d5 d8 ff ff       	call   c0101fe9 <intr_enable>
}
c0104714:	90                   	nop
c0104715:	89 ec                	mov    %ebp,%esp
c0104717:	5d                   	pop    %ebp
c0104718:	c3                   	ret    

c0104719 <page2ppn>:
page2ppn(struct Page *page) {
c0104719:	55                   	push   %ebp
c010471a:	89 e5                	mov    %esp,%ebp
    return page - pages;
c010471c:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c0104722:	8b 45 08             	mov    0x8(%ebp),%eax
c0104725:	29 d0                	sub    %edx,%eax
c0104727:	c1 f8 05             	sar    $0x5,%eax
}
c010472a:	5d                   	pop    %ebp
c010472b:	c3                   	ret    

c010472c <page2pa>:
page2pa(struct Page *page) {
c010472c:	55                   	push   %ebp
c010472d:	89 e5                	mov    %esp,%ebp
c010472f:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0104732:	8b 45 08             	mov    0x8(%ebp),%eax
c0104735:	89 04 24             	mov    %eax,(%esp)
c0104738:	e8 dc ff ff ff       	call   c0104719 <page2ppn>
c010473d:	c1 e0 0c             	shl    $0xc,%eax
}
c0104740:	89 ec                	mov    %ebp,%esp
c0104742:	5d                   	pop    %ebp
c0104743:	c3                   	ret    

c0104744 <pa2page>:
pa2page(uintptr_t pa) {
c0104744:	55                   	push   %ebp
c0104745:	89 e5                	mov    %esp,%ebp
c0104747:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c010474a:	8b 45 08             	mov    0x8(%ebp),%eax
c010474d:	c1 e8 0c             	shr    $0xc,%eax
c0104750:	89 c2                	mov    %eax,%edx
c0104752:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0104757:	39 c2                	cmp    %eax,%edx
c0104759:	72 1c                	jb     c0104777 <pa2page+0x33>
        panic("pa2page called with invalid pa");
c010475b:	c7 44 24 08 dc cc 10 	movl   $0xc010ccdc,0x8(%esp)
c0104762:	c0 
c0104763:	c7 44 24 04 5e 00 00 	movl   $0x5e,0x4(%esp)
c010476a:	00 
c010476b:	c7 04 24 fb cc 10 c0 	movl   $0xc010ccfb,(%esp)
c0104772:	e8 c4 c5 ff ff       	call   c0100d3b <__panic>
    return &pages[PPN(pa)];
c0104777:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c010477d:	8b 45 08             	mov    0x8(%ebp),%eax
c0104780:	c1 e8 0c             	shr    $0xc,%eax
c0104783:	c1 e0 05             	shl    $0x5,%eax
c0104786:	01 d0                	add    %edx,%eax
}
c0104788:	89 ec                	mov    %ebp,%esp
c010478a:	5d                   	pop    %ebp
c010478b:	c3                   	ret    

c010478c <page2kva>:
page2kva(struct Page *page) {
c010478c:	55                   	push   %ebp
c010478d:	89 e5                	mov    %esp,%ebp
c010478f:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c0104792:	8b 45 08             	mov    0x8(%ebp),%eax
c0104795:	89 04 24             	mov    %eax,(%esp)
c0104798:	e8 8f ff ff ff       	call   c010472c <page2pa>
c010479d:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01047a0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01047a3:	c1 e8 0c             	shr    $0xc,%eax
c01047a6:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01047a9:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c01047ae:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01047b1:	72 23                	jb     c01047d6 <page2kva+0x4a>
c01047b3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01047b6:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01047ba:	c7 44 24 08 0c cd 10 	movl   $0xc010cd0c,0x8(%esp)
c01047c1:	c0 
c01047c2:	c7 44 24 04 65 00 00 	movl   $0x65,0x4(%esp)
c01047c9:	00 
c01047ca:	c7 04 24 fb cc 10 c0 	movl   $0xc010ccfb,(%esp)
c01047d1:	e8 65 c5 ff ff       	call   c0100d3b <__panic>
c01047d6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01047d9:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c01047de:	89 ec                	mov    %ebp,%esp
c01047e0:	5d                   	pop    %ebp
c01047e1:	c3                   	ret    

c01047e2 <kva2page>:
kva2page(void *kva) {
c01047e2:	55                   	push   %ebp
c01047e3:	89 e5                	mov    %esp,%ebp
c01047e5:	83 ec 28             	sub    $0x28,%esp
    return pa2page(PADDR(kva));
c01047e8:	8b 45 08             	mov    0x8(%ebp),%eax
c01047eb:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01047ee:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c01047f5:	77 23                	ja     c010481a <kva2page+0x38>
c01047f7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01047fa:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01047fe:	c7 44 24 08 30 cd 10 	movl   $0xc010cd30,0x8(%esp)
c0104805:	c0 
c0104806:	c7 44 24 04 6a 00 00 	movl   $0x6a,0x4(%esp)
c010480d:	00 
c010480e:	c7 04 24 fb cc 10 c0 	movl   $0xc010ccfb,(%esp)
c0104815:	e8 21 c5 ff ff       	call   c0100d3b <__panic>
c010481a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010481d:	05 00 00 00 40       	add    $0x40000000,%eax
c0104822:	89 04 24             	mov    %eax,(%esp)
c0104825:	e8 1a ff ff ff       	call   c0104744 <pa2page>
}
c010482a:	89 ec                	mov    %ebp,%esp
c010482c:	5d                   	pop    %ebp
c010482d:	c3                   	ret    

c010482e <__slob_get_free_pages>:
static slob_t *slobfree = &arena;
static bigblock_t *bigblocks;


static void* __slob_get_free_pages(gfp_t gfp, int order)
{
c010482e:	55                   	push   %ebp
c010482f:	89 e5                	mov    %esp,%ebp
c0104831:	83 ec 28             	sub    $0x28,%esp
  struct Page * page = alloc_pages(1 << order);
c0104834:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104837:	ba 01 00 00 00       	mov    $0x1,%edx
c010483c:	88 c1                	mov    %al,%cl
c010483e:	d3 e2                	shl    %cl,%edx
c0104840:	89 d0                	mov    %edx,%eax
c0104842:	89 04 24             	mov    %eax,(%esp)
c0104845:	e8 37 09 00 00       	call   c0105181 <alloc_pages>
c010484a:	89 45 f4             	mov    %eax,-0xc(%ebp)
  if(!page)
c010484d:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104851:	75 07                	jne    c010485a <__slob_get_free_pages+0x2c>
    return NULL;
c0104853:	b8 00 00 00 00       	mov    $0x0,%eax
c0104858:	eb 0b                	jmp    c0104865 <__slob_get_free_pages+0x37>
  return page2kva(page);
c010485a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010485d:	89 04 24             	mov    %eax,(%esp)
c0104860:	e8 27 ff ff ff       	call   c010478c <page2kva>
}
c0104865:	89 ec                	mov    %ebp,%esp
c0104867:	5d                   	pop    %ebp
c0104868:	c3                   	ret    

c0104869 <__slob_free_pages>:

#define __slob_get_free_page(gfp) __slob_get_free_pages(gfp, 0)

static inline void __slob_free_pages(unsigned long kva, int order)
{
c0104869:	55                   	push   %ebp
c010486a:	89 e5                	mov    %esp,%ebp
c010486c:	83 ec 18             	sub    $0x18,%esp
c010486f:	89 5d fc             	mov    %ebx,-0x4(%ebp)
  free_pages(kva2page(kva), 1 << order);
c0104872:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104875:	ba 01 00 00 00       	mov    $0x1,%edx
c010487a:	88 c1                	mov    %al,%cl
c010487c:	d3 e2                	shl    %cl,%edx
c010487e:	89 d0                	mov    %edx,%eax
c0104880:	89 c3                	mov    %eax,%ebx
c0104882:	8b 45 08             	mov    0x8(%ebp),%eax
c0104885:	89 04 24             	mov    %eax,(%esp)
c0104888:	e8 55 ff ff ff       	call   c01047e2 <kva2page>
c010488d:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c0104891:	89 04 24             	mov    %eax,(%esp)
c0104894:	e8 55 09 00 00       	call   c01051ee <free_pages>
}
c0104899:	90                   	nop
c010489a:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c010489d:	89 ec                	mov    %ebp,%esp
c010489f:	5d                   	pop    %ebp
c01048a0:	c3                   	ret    

c01048a1 <slob_alloc>:

static void slob_free(void *b, int size);

static void *slob_alloc(size_t size, gfp_t gfp, int align)
{
c01048a1:	55                   	push   %ebp
c01048a2:	89 e5                	mov    %esp,%ebp
c01048a4:	83 ec 38             	sub    $0x38,%esp
  assert( (size + SLOB_UNIT) < PAGE_SIZE );
c01048a7:	8b 45 08             	mov    0x8(%ebp),%eax
c01048aa:	83 c0 08             	add    $0x8,%eax
c01048ad:	3d ff 0f 00 00       	cmp    $0xfff,%eax
c01048b2:	76 24                	jbe    c01048d8 <slob_alloc+0x37>
c01048b4:	c7 44 24 0c 54 cd 10 	movl   $0xc010cd54,0xc(%esp)
c01048bb:	c0 
c01048bc:	c7 44 24 08 73 cd 10 	movl   $0xc010cd73,0x8(%esp)
c01048c3:	c0 
c01048c4:	c7 44 24 04 64 00 00 	movl   $0x64,0x4(%esp)
c01048cb:	00 
c01048cc:	c7 04 24 88 cd 10 c0 	movl   $0xc010cd88,(%esp)
c01048d3:	e8 63 c4 ff ff       	call   c0100d3b <__panic>

	slob_t *prev, *cur, *aligned = 0;
c01048d8:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
	int delta = 0, units = SLOB_UNITS(size);
c01048df:	c7 45 e8 00 00 00 00 	movl   $0x0,-0x18(%ebp)
c01048e6:	8b 45 08             	mov    0x8(%ebp),%eax
c01048e9:	83 c0 07             	add    $0x7,%eax
c01048ec:	c1 e8 03             	shr    $0x3,%eax
c01048ef:	89 45 e0             	mov    %eax,-0x20(%ebp)
	unsigned long flags;

	spin_lock_irqsave(&slob_lock, flags);
c01048f2:	e8 e0 fd ff ff       	call   c01046d7 <__intr_save>
c01048f7:	89 45 e4             	mov    %eax,-0x1c(%ebp)
	prev = slobfree;
c01048fa:	a1 e8 f9 12 c0       	mov    0xc012f9e8,%eax
c01048ff:	89 45 f4             	mov    %eax,-0xc(%ebp)
	for (cur = prev->next; ; prev = cur, cur = cur->next) {
c0104902:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104905:	8b 40 04             	mov    0x4(%eax),%eax
c0104908:	89 45 f0             	mov    %eax,-0x10(%ebp)
		if (align) {
c010490b:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010490f:	74 21                	je     c0104932 <slob_alloc+0x91>
			aligned = (slob_t *)ALIGN((unsigned long)cur, align);
c0104911:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0104914:	8b 45 10             	mov    0x10(%ebp),%eax
c0104917:	01 d0                	add    %edx,%eax
c0104919:	8d 50 ff             	lea    -0x1(%eax),%edx
c010491c:	8b 45 10             	mov    0x10(%ebp),%eax
c010491f:	f7 d8                	neg    %eax
c0104921:	21 d0                	and    %edx,%eax
c0104923:	89 45 ec             	mov    %eax,-0x14(%ebp)
			delta = aligned - cur;
c0104926:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104929:	2b 45 f0             	sub    -0x10(%ebp),%eax
c010492c:	c1 f8 03             	sar    $0x3,%eax
c010492f:	89 45 e8             	mov    %eax,-0x18(%ebp)
		}
		if (cur->units >= units + delta) { /* room enough? */
c0104932:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104935:	8b 00                	mov    (%eax),%eax
c0104937:	8b 4d e0             	mov    -0x20(%ebp),%ecx
c010493a:	8b 55 e8             	mov    -0x18(%ebp),%edx
c010493d:	01 ca                	add    %ecx,%edx
c010493f:	39 d0                	cmp    %edx,%eax
c0104941:	0f 8c aa 00 00 00    	jl     c01049f1 <slob_alloc+0x150>
			if (delta) { /* need to fragment head to align? */
c0104947:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010494b:	74 38                	je     c0104985 <slob_alloc+0xe4>
				aligned->units = cur->units - delta;
c010494d:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104950:	8b 00                	mov    (%eax),%eax
c0104952:	2b 45 e8             	sub    -0x18(%ebp),%eax
c0104955:	89 c2                	mov    %eax,%edx
c0104957:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010495a:	89 10                	mov    %edx,(%eax)
				aligned->next = cur->next;
c010495c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010495f:	8b 50 04             	mov    0x4(%eax),%edx
c0104962:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104965:	89 50 04             	mov    %edx,0x4(%eax)
				cur->next = aligned;
c0104968:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010496b:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010496e:	89 50 04             	mov    %edx,0x4(%eax)
				cur->units = delta;
c0104971:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104974:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0104977:	89 10                	mov    %edx,(%eax)
				prev = cur;
c0104979:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010497c:	89 45 f4             	mov    %eax,-0xc(%ebp)
				cur = aligned;
c010497f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104982:	89 45 f0             	mov    %eax,-0x10(%ebp)
			}

			if (cur->units == units) /* exact fit? */
c0104985:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104988:	8b 00                	mov    (%eax),%eax
c010498a:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c010498d:	75 0e                	jne    c010499d <slob_alloc+0xfc>
				prev->next = cur->next; /* unlink */
c010498f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104992:	8b 50 04             	mov    0x4(%eax),%edx
c0104995:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104998:	89 50 04             	mov    %edx,0x4(%eax)
c010499b:	eb 3c                	jmp    c01049d9 <slob_alloc+0x138>
			else { /* fragment */
				prev->next = cur + units;
c010499d:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01049a0:	8d 14 c5 00 00 00 00 	lea    0x0(,%eax,8),%edx
c01049a7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01049aa:	01 c2                	add    %eax,%edx
c01049ac:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049af:	89 50 04             	mov    %edx,0x4(%eax)
				prev->next->units = cur->units - units;
c01049b2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01049b5:	8b 10                	mov    (%eax),%edx
c01049b7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049ba:	8b 40 04             	mov    0x4(%eax),%eax
c01049bd:	2b 55 e0             	sub    -0x20(%ebp),%edx
c01049c0:	89 10                	mov    %edx,(%eax)
				prev->next->next = cur->next;
c01049c2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049c5:	8b 40 04             	mov    0x4(%eax),%eax
c01049c8:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01049cb:	8b 52 04             	mov    0x4(%edx),%edx
c01049ce:	89 50 04             	mov    %edx,0x4(%eax)
				cur->units = units;
c01049d1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01049d4:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01049d7:	89 10                	mov    %edx,(%eax)
			}

			slobfree = prev;
c01049d9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049dc:	a3 e8 f9 12 c0       	mov    %eax,0xc012f9e8
			spin_unlock_irqrestore(&slob_lock, flags);
c01049e1:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01049e4:	89 04 24             	mov    %eax,(%esp)
c01049e7:	e8 17 fd ff ff       	call   c0104703 <__intr_restore>
			return cur;
c01049ec:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01049ef:	eb 7f                	jmp    c0104a70 <slob_alloc+0x1cf>
		}
		if (cur == slobfree) {
c01049f1:	a1 e8 f9 12 c0       	mov    0xc012f9e8,%eax
c01049f6:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01049f9:	75 61                	jne    c0104a5c <slob_alloc+0x1bb>
			spin_unlock_irqrestore(&slob_lock, flags);
c01049fb:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01049fe:	89 04 24             	mov    %eax,(%esp)
c0104a01:	e8 fd fc ff ff       	call   c0104703 <__intr_restore>

			if (size == PAGE_SIZE) /* trying to shrink arena? */
c0104a06:	81 7d 08 00 10 00 00 	cmpl   $0x1000,0x8(%ebp)
c0104a0d:	75 07                	jne    c0104a16 <slob_alloc+0x175>
				return 0;
c0104a0f:	b8 00 00 00 00       	mov    $0x0,%eax
c0104a14:	eb 5a                	jmp    c0104a70 <slob_alloc+0x1cf>

			cur = (slob_t *)__slob_get_free_page(gfp);
c0104a16:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0104a1d:	00 
c0104a1e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104a21:	89 04 24             	mov    %eax,(%esp)
c0104a24:	e8 05 fe ff ff       	call   c010482e <__slob_get_free_pages>
c0104a29:	89 45 f0             	mov    %eax,-0x10(%ebp)
			if (!cur)
c0104a2c:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0104a30:	75 07                	jne    c0104a39 <slob_alloc+0x198>
				return 0;
c0104a32:	b8 00 00 00 00       	mov    $0x0,%eax
c0104a37:	eb 37                	jmp    c0104a70 <slob_alloc+0x1cf>

			slob_free(cur, PAGE_SIZE);
c0104a39:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0104a40:	00 
c0104a41:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104a44:	89 04 24             	mov    %eax,(%esp)
c0104a47:	e8 28 00 00 00       	call   c0104a74 <slob_free>
			spin_lock_irqsave(&slob_lock, flags);
c0104a4c:	e8 86 fc ff ff       	call   c01046d7 <__intr_save>
c0104a51:	89 45 e4             	mov    %eax,-0x1c(%ebp)
			cur = slobfree;
c0104a54:	a1 e8 f9 12 c0       	mov    0xc012f9e8,%eax
c0104a59:	89 45 f0             	mov    %eax,-0x10(%ebp)
	for (cur = prev->next; ; prev = cur, cur = cur->next) {
c0104a5c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104a5f:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104a62:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104a65:	8b 40 04             	mov    0x4(%eax),%eax
c0104a68:	89 45 f0             	mov    %eax,-0x10(%ebp)
		if (align) {
c0104a6b:	e9 9b fe ff ff       	jmp    c010490b <slob_alloc+0x6a>
		}
	}
}
c0104a70:	89 ec                	mov    %ebp,%esp
c0104a72:	5d                   	pop    %ebp
c0104a73:	c3                   	ret    

c0104a74 <slob_free>:

static void slob_free(void *block, int size)
{
c0104a74:	55                   	push   %ebp
c0104a75:	89 e5                	mov    %esp,%ebp
c0104a77:	83 ec 28             	sub    $0x28,%esp
	slob_t *cur, *b = (slob_t *)block;
c0104a7a:	8b 45 08             	mov    0x8(%ebp),%eax
c0104a7d:	89 45 f0             	mov    %eax,-0x10(%ebp)
	unsigned long flags;

	if (!block)
c0104a80:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104a84:	0f 84 01 01 00 00    	je     c0104b8b <slob_free+0x117>
		return;

	if (size)
c0104a8a:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0104a8e:	74 10                	je     c0104aa0 <slob_free+0x2c>
		b->units = SLOB_UNITS(size);
c0104a90:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104a93:	83 c0 07             	add    $0x7,%eax
c0104a96:	c1 e8 03             	shr    $0x3,%eax
c0104a99:	89 c2                	mov    %eax,%edx
c0104a9b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104a9e:	89 10                	mov    %edx,(%eax)

	/* Find reinsertion point */
	spin_lock_irqsave(&slob_lock, flags);
c0104aa0:	e8 32 fc ff ff       	call   c01046d7 <__intr_save>
c0104aa5:	89 45 ec             	mov    %eax,-0x14(%ebp)
	for (cur = slobfree; !(b > cur && b < cur->next); cur = cur->next)
c0104aa8:	a1 e8 f9 12 c0       	mov    0xc012f9e8,%eax
c0104aad:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104ab0:	eb 27                	jmp    c0104ad9 <slob_free+0x65>
		if (cur >= cur->next && (b > cur || b < cur->next))
c0104ab2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104ab5:	8b 40 04             	mov    0x4(%eax),%eax
c0104ab8:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0104abb:	72 13                	jb     c0104ad0 <slob_free+0x5c>
c0104abd:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104ac0:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0104ac3:	77 27                	ja     c0104aec <slob_free+0x78>
c0104ac5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104ac8:	8b 40 04             	mov    0x4(%eax),%eax
c0104acb:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0104ace:	72 1c                	jb     c0104aec <slob_free+0x78>
	for (cur = slobfree; !(b > cur && b < cur->next); cur = cur->next)
c0104ad0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104ad3:	8b 40 04             	mov    0x4(%eax),%eax
c0104ad6:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104ad9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104adc:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0104adf:	76 d1                	jbe    c0104ab2 <slob_free+0x3e>
c0104ae1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104ae4:	8b 40 04             	mov    0x4(%eax),%eax
c0104ae7:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0104aea:	73 c6                	jae    c0104ab2 <slob_free+0x3e>
			break;

	if (b + b->units == cur->next) {
c0104aec:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104aef:	8b 00                	mov    (%eax),%eax
c0104af1:	8d 14 c5 00 00 00 00 	lea    0x0(,%eax,8),%edx
c0104af8:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104afb:	01 c2                	add    %eax,%edx
c0104afd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b00:	8b 40 04             	mov    0x4(%eax),%eax
c0104b03:	39 c2                	cmp    %eax,%edx
c0104b05:	75 25                	jne    c0104b2c <slob_free+0xb8>
		b->units += cur->next->units;
c0104b07:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104b0a:	8b 10                	mov    (%eax),%edx
c0104b0c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b0f:	8b 40 04             	mov    0x4(%eax),%eax
c0104b12:	8b 00                	mov    (%eax),%eax
c0104b14:	01 c2                	add    %eax,%edx
c0104b16:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104b19:	89 10                	mov    %edx,(%eax)
		b->next = cur->next->next;
c0104b1b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b1e:	8b 40 04             	mov    0x4(%eax),%eax
c0104b21:	8b 50 04             	mov    0x4(%eax),%edx
c0104b24:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104b27:	89 50 04             	mov    %edx,0x4(%eax)
c0104b2a:	eb 0c                	jmp    c0104b38 <slob_free+0xc4>
	} else
		b->next = cur->next;
c0104b2c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b2f:	8b 50 04             	mov    0x4(%eax),%edx
c0104b32:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104b35:	89 50 04             	mov    %edx,0x4(%eax)

	if (cur + cur->units == b) {
c0104b38:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b3b:	8b 00                	mov    (%eax),%eax
c0104b3d:	8d 14 c5 00 00 00 00 	lea    0x0(,%eax,8),%edx
c0104b44:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b47:	01 d0                	add    %edx,%eax
c0104b49:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0104b4c:	75 1f                	jne    c0104b6d <slob_free+0xf9>
		cur->units += b->units;
c0104b4e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b51:	8b 10                	mov    (%eax),%edx
c0104b53:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104b56:	8b 00                	mov    (%eax),%eax
c0104b58:	01 c2                	add    %eax,%edx
c0104b5a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b5d:	89 10                	mov    %edx,(%eax)
		cur->next = b->next;
c0104b5f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104b62:	8b 50 04             	mov    0x4(%eax),%edx
c0104b65:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b68:	89 50 04             	mov    %edx,0x4(%eax)
c0104b6b:	eb 09                	jmp    c0104b76 <slob_free+0x102>
	} else
		cur->next = b;
c0104b6d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b70:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0104b73:	89 50 04             	mov    %edx,0x4(%eax)

	slobfree = cur;
c0104b76:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b79:	a3 e8 f9 12 c0       	mov    %eax,0xc012f9e8

	spin_unlock_irqrestore(&slob_lock, flags);
c0104b7e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104b81:	89 04 24             	mov    %eax,(%esp)
c0104b84:	e8 7a fb ff ff       	call   c0104703 <__intr_restore>
c0104b89:	eb 01                	jmp    c0104b8c <slob_free+0x118>
		return;
c0104b8b:	90                   	nop
}
c0104b8c:	89 ec                	mov    %ebp,%esp
c0104b8e:	5d                   	pop    %ebp
c0104b8f:	c3                   	ret    

c0104b90 <slob_init>:



void
slob_init(void) {
c0104b90:	55                   	push   %ebp
c0104b91:	89 e5                	mov    %esp,%ebp
c0104b93:	83 ec 18             	sub    $0x18,%esp
  cprintf("use SLOB allocator\n");
c0104b96:	c7 04 24 9a cd 10 c0 	movl   $0xc010cd9a,(%esp)
c0104b9d:	e8 d6 b7 ff ff       	call   c0100378 <cprintf>
}
c0104ba2:	90                   	nop
c0104ba3:	89 ec                	mov    %ebp,%esp
c0104ba5:	5d                   	pop    %ebp
c0104ba6:	c3                   	ret    

c0104ba7 <kmalloc_init>:

inline void 
kmalloc_init(void) {
c0104ba7:	55                   	push   %ebp
c0104ba8:	89 e5                	mov    %esp,%ebp
c0104baa:	83 ec 18             	sub    $0x18,%esp
    slob_init();
c0104bad:	e8 de ff ff ff       	call   c0104b90 <slob_init>
    cprintf("kmalloc_init() succeeded!\n");
c0104bb2:	c7 04 24 ae cd 10 c0 	movl   $0xc010cdae,(%esp)
c0104bb9:	e8 ba b7 ff ff       	call   c0100378 <cprintf>
}
c0104bbe:	90                   	nop
c0104bbf:	89 ec                	mov    %ebp,%esp
c0104bc1:	5d                   	pop    %ebp
c0104bc2:	c3                   	ret    

c0104bc3 <slob_allocated>:

size_t
slob_allocated(void) {
c0104bc3:	55                   	push   %ebp
c0104bc4:	89 e5                	mov    %esp,%ebp
  return 0;
c0104bc6:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104bcb:	5d                   	pop    %ebp
c0104bcc:	c3                   	ret    

c0104bcd <kallocated>:

size_t
kallocated(void) {
c0104bcd:	55                   	push   %ebp
c0104bce:	89 e5                	mov    %esp,%ebp
   return slob_allocated();
c0104bd0:	e8 ee ff ff ff       	call   c0104bc3 <slob_allocated>
}
c0104bd5:	5d                   	pop    %ebp
c0104bd6:	c3                   	ret    

c0104bd7 <find_order>:

static int find_order(int size)
{
c0104bd7:	55                   	push   %ebp
c0104bd8:	89 e5                	mov    %esp,%ebp
c0104bda:	83 ec 10             	sub    $0x10,%esp
	int order = 0;
c0104bdd:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
	for ( ; size > 4096 ; size >>=1)
c0104be4:	eb 06                	jmp    c0104bec <find_order+0x15>
		order++;
c0104be6:	ff 45 fc             	incl   -0x4(%ebp)
	for ( ; size > 4096 ; size >>=1)
c0104be9:	d1 7d 08             	sarl   0x8(%ebp)
c0104bec:	81 7d 08 00 10 00 00 	cmpl   $0x1000,0x8(%ebp)
c0104bf3:	7f f1                	jg     c0104be6 <find_order+0xf>
	return order;
c0104bf5:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0104bf8:	89 ec                	mov    %ebp,%esp
c0104bfa:	5d                   	pop    %ebp
c0104bfb:	c3                   	ret    

c0104bfc <__kmalloc>:

static void *__kmalloc(size_t size, gfp_t gfp)
{
c0104bfc:	55                   	push   %ebp
c0104bfd:	89 e5                	mov    %esp,%ebp
c0104bff:	83 ec 28             	sub    $0x28,%esp
	slob_t *m;
	bigblock_t *bb;
	unsigned long flags;

	if (size < PAGE_SIZE - SLOB_UNIT) {
c0104c02:	81 7d 08 f7 0f 00 00 	cmpl   $0xff7,0x8(%ebp)
c0104c09:	77 3b                	ja     c0104c46 <__kmalloc+0x4a>
		m = slob_alloc(size + SLOB_UNIT, gfp, 0);
c0104c0b:	8b 45 08             	mov    0x8(%ebp),%eax
c0104c0e:	8d 50 08             	lea    0x8(%eax),%edx
c0104c11:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0104c18:	00 
c0104c19:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104c1c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104c20:	89 14 24             	mov    %edx,(%esp)
c0104c23:	e8 79 fc ff ff       	call   c01048a1 <slob_alloc>
c0104c28:	89 45 ec             	mov    %eax,-0x14(%ebp)
		return m ? (void *)(m + 1) : 0;
c0104c2b:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0104c2f:	74 0b                	je     c0104c3c <__kmalloc+0x40>
c0104c31:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104c34:	83 c0 08             	add    $0x8,%eax
c0104c37:	e9 b0 00 00 00       	jmp    c0104cec <__kmalloc+0xf0>
c0104c3c:	b8 00 00 00 00       	mov    $0x0,%eax
c0104c41:	e9 a6 00 00 00       	jmp    c0104cec <__kmalloc+0xf0>
	}

	bb = slob_alloc(sizeof(bigblock_t), gfp, 0);
c0104c46:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0104c4d:	00 
c0104c4e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104c51:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104c55:	c7 04 24 0c 00 00 00 	movl   $0xc,(%esp)
c0104c5c:	e8 40 fc ff ff       	call   c01048a1 <slob_alloc>
c0104c61:	89 45 f4             	mov    %eax,-0xc(%ebp)
	if (!bb)
c0104c64:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104c68:	75 07                	jne    c0104c71 <__kmalloc+0x75>
		return 0;
c0104c6a:	b8 00 00 00 00       	mov    $0x0,%eax
c0104c6f:	eb 7b                	jmp    c0104cec <__kmalloc+0xf0>

	bb->order = find_order(size);
c0104c71:	8b 45 08             	mov    0x8(%ebp),%eax
c0104c74:	89 04 24             	mov    %eax,(%esp)
c0104c77:	e8 5b ff ff ff       	call   c0104bd7 <find_order>
c0104c7c:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0104c7f:	89 02                	mov    %eax,(%edx)
	bb->pages = (void *)__slob_get_free_pages(gfp, bb->order);
c0104c81:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104c84:	8b 00                	mov    (%eax),%eax
c0104c86:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104c8a:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104c8d:	89 04 24             	mov    %eax,(%esp)
c0104c90:	e8 99 fb ff ff       	call   c010482e <__slob_get_free_pages>
c0104c95:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0104c98:	89 42 04             	mov    %eax,0x4(%edx)

	if (bb->pages) {
c0104c9b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104c9e:	8b 40 04             	mov    0x4(%eax),%eax
c0104ca1:	85 c0                	test   %eax,%eax
c0104ca3:	74 2f                	je     c0104cd4 <__kmalloc+0xd8>
		spin_lock_irqsave(&block_lock, flags);
c0104ca5:	e8 2d fa ff ff       	call   c01046d7 <__intr_save>
c0104caa:	89 45 f0             	mov    %eax,-0x10(%ebp)
		bb->next = bigblocks;
c0104cad:	8b 15 90 3f 1a c0    	mov    0xc01a3f90,%edx
c0104cb3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104cb6:	89 50 08             	mov    %edx,0x8(%eax)
		bigblocks = bb;
c0104cb9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104cbc:	a3 90 3f 1a c0       	mov    %eax,0xc01a3f90
		spin_unlock_irqrestore(&block_lock, flags);
c0104cc1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104cc4:	89 04 24             	mov    %eax,(%esp)
c0104cc7:	e8 37 fa ff ff       	call   c0104703 <__intr_restore>
		return bb->pages;
c0104ccc:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104ccf:	8b 40 04             	mov    0x4(%eax),%eax
c0104cd2:	eb 18                	jmp    c0104cec <__kmalloc+0xf0>
	}

	slob_free(bb, sizeof(bigblock_t));
c0104cd4:	c7 44 24 04 0c 00 00 	movl   $0xc,0x4(%esp)
c0104cdb:	00 
c0104cdc:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104cdf:	89 04 24             	mov    %eax,(%esp)
c0104ce2:	e8 8d fd ff ff       	call   c0104a74 <slob_free>
	return 0;
c0104ce7:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104cec:	89 ec                	mov    %ebp,%esp
c0104cee:	5d                   	pop    %ebp
c0104cef:	c3                   	ret    

c0104cf0 <kmalloc>:

void *
kmalloc(size_t size)
{
c0104cf0:	55                   	push   %ebp
c0104cf1:	89 e5                	mov    %esp,%ebp
c0104cf3:	83 ec 18             	sub    $0x18,%esp
  return __kmalloc(size, 0);
c0104cf6:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0104cfd:	00 
c0104cfe:	8b 45 08             	mov    0x8(%ebp),%eax
c0104d01:	89 04 24             	mov    %eax,(%esp)
c0104d04:	e8 f3 fe ff ff       	call   c0104bfc <__kmalloc>
}
c0104d09:	89 ec                	mov    %ebp,%esp
c0104d0b:	5d                   	pop    %ebp
c0104d0c:	c3                   	ret    

c0104d0d <kfree>:


void kfree(void *block)
{
c0104d0d:	55                   	push   %ebp
c0104d0e:	89 e5                	mov    %esp,%ebp
c0104d10:	83 ec 28             	sub    $0x28,%esp
	bigblock_t *bb, **last = &bigblocks;
c0104d13:	c7 45 f0 90 3f 1a c0 	movl   $0xc01a3f90,-0x10(%ebp)
	unsigned long flags;

	if (!block)
c0104d1a:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104d1e:	0f 84 a3 00 00 00    	je     c0104dc7 <kfree+0xba>
		return;

	if (!((unsigned long)block & (PAGE_SIZE-1))) {
c0104d24:	8b 45 08             	mov    0x8(%ebp),%eax
c0104d27:	25 ff 0f 00 00       	and    $0xfff,%eax
c0104d2c:	85 c0                	test   %eax,%eax
c0104d2e:	75 7f                	jne    c0104daf <kfree+0xa2>
		/* might be on the big block list */
		spin_lock_irqsave(&block_lock, flags);
c0104d30:	e8 a2 f9 ff ff       	call   c01046d7 <__intr_save>
c0104d35:	89 45 ec             	mov    %eax,-0x14(%ebp)
		for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
c0104d38:	a1 90 3f 1a c0       	mov    0xc01a3f90,%eax
c0104d3d:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104d40:	eb 5c                	jmp    c0104d9e <kfree+0x91>
			if (bb->pages == block) {
c0104d42:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d45:	8b 40 04             	mov    0x4(%eax),%eax
c0104d48:	39 45 08             	cmp    %eax,0x8(%ebp)
c0104d4b:	75 3f                	jne    c0104d8c <kfree+0x7f>
				*last = bb->next;
c0104d4d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d50:	8b 50 08             	mov    0x8(%eax),%edx
c0104d53:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104d56:	89 10                	mov    %edx,(%eax)
				spin_unlock_irqrestore(&block_lock, flags);
c0104d58:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104d5b:	89 04 24             	mov    %eax,(%esp)
c0104d5e:	e8 a0 f9 ff ff       	call   c0104703 <__intr_restore>
				__slob_free_pages((unsigned long)block, bb->order);
c0104d63:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d66:	8b 10                	mov    (%eax),%edx
c0104d68:	8b 45 08             	mov    0x8(%ebp),%eax
c0104d6b:	89 54 24 04          	mov    %edx,0x4(%esp)
c0104d6f:	89 04 24             	mov    %eax,(%esp)
c0104d72:	e8 f2 fa ff ff       	call   c0104869 <__slob_free_pages>
				slob_free(bb, sizeof(bigblock_t));
c0104d77:	c7 44 24 04 0c 00 00 	movl   $0xc,0x4(%esp)
c0104d7e:	00 
c0104d7f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d82:	89 04 24             	mov    %eax,(%esp)
c0104d85:	e8 ea fc ff ff       	call   c0104a74 <slob_free>
				return;
c0104d8a:	eb 3c                	jmp    c0104dc8 <kfree+0xbb>
		for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
c0104d8c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d8f:	83 c0 08             	add    $0x8,%eax
c0104d92:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0104d95:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d98:	8b 40 08             	mov    0x8(%eax),%eax
c0104d9b:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104d9e:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104da2:	75 9e                	jne    c0104d42 <kfree+0x35>
			}
		}
		spin_unlock_irqrestore(&block_lock, flags);
c0104da4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104da7:	89 04 24             	mov    %eax,(%esp)
c0104daa:	e8 54 f9 ff ff       	call   c0104703 <__intr_restore>
	}

	slob_free((slob_t *)block - 1, 0);
c0104daf:	8b 45 08             	mov    0x8(%ebp),%eax
c0104db2:	83 e8 08             	sub    $0x8,%eax
c0104db5:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0104dbc:	00 
c0104dbd:	89 04 24             	mov    %eax,(%esp)
c0104dc0:	e8 af fc ff ff       	call   c0104a74 <slob_free>
	return;
c0104dc5:	eb 01                	jmp    c0104dc8 <kfree+0xbb>
		return;
c0104dc7:	90                   	nop
}
c0104dc8:	89 ec                	mov    %ebp,%esp
c0104dca:	5d                   	pop    %ebp
c0104dcb:	c3                   	ret    

c0104dcc <ksize>:


unsigned int ksize(const void *block)
{
c0104dcc:	55                   	push   %ebp
c0104dcd:	89 e5                	mov    %esp,%ebp
c0104dcf:	83 ec 28             	sub    $0x28,%esp
	bigblock_t *bb;
	unsigned long flags;

	if (!block)
c0104dd2:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104dd6:	75 07                	jne    c0104ddf <ksize+0x13>
		return 0;
c0104dd8:	b8 00 00 00 00       	mov    $0x0,%eax
c0104ddd:	eb 6b                	jmp    c0104e4a <ksize+0x7e>

	if (!((unsigned long)block & (PAGE_SIZE-1))) {
c0104ddf:	8b 45 08             	mov    0x8(%ebp),%eax
c0104de2:	25 ff 0f 00 00       	and    $0xfff,%eax
c0104de7:	85 c0                	test   %eax,%eax
c0104de9:	75 54                	jne    c0104e3f <ksize+0x73>
		spin_lock_irqsave(&block_lock, flags);
c0104deb:	e8 e7 f8 ff ff       	call   c01046d7 <__intr_save>
c0104df0:	89 45 f0             	mov    %eax,-0x10(%ebp)
		for (bb = bigblocks; bb; bb = bb->next)
c0104df3:	a1 90 3f 1a c0       	mov    0xc01a3f90,%eax
c0104df8:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104dfb:	eb 31                	jmp    c0104e2e <ksize+0x62>
			if (bb->pages == block) {
c0104dfd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104e00:	8b 40 04             	mov    0x4(%eax),%eax
c0104e03:	39 45 08             	cmp    %eax,0x8(%ebp)
c0104e06:	75 1d                	jne    c0104e25 <ksize+0x59>
				spin_unlock_irqrestore(&slob_lock, flags);
c0104e08:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104e0b:	89 04 24             	mov    %eax,(%esp)
c0104e0e:	e8 f0 f8 ff ff       	call   c0104703 <__intr_restore>
				return PAGE_SIZE << bb->order;
c0104e13:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104e16:	8b 00                	mov    (%eax),%eax
c0104e18:	ba 00 10 00 00       	mov    $0x1000,%edx
c0104e1d:	88 c1                	mov    %al,%cl
c0104e1f:	d3 e2                	shl    %cl,%edx
c0104e21:	89 d0                	mov    %edx,%eax
c0104e23:	eb 25                	jmp    c0104e4a <ksize+0x7e>
		for (bb = bigblocks; bb; bb = bb->next)
c0104e25:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104e28:	8b 40 08             	mov    0x8(%eax),%eax
c0104e2b:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104e2e:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104e32:	75 c9                	jne    c0104dfd <ksize+0x31>
			}
		spin_unlock_irqrestore(&block_lock, flags);
c0104e34:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104e37:	89 04 24             	mov    %eax,(%esp)
c0104e3a:	e8 c4 f8 ff ff       	call   c0104703 <__intr_restore>
	}

	return ((slob_t *)block - 1)->units * SLOB_UNIT;
c0104e3f:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e42:	83 e8 08             	sub    $0x8,%eax
c0104e45:	8b 00                	mov    (%eax),%eax
c0104e47:	c1 e0 03             	shl    $0x3,%eax
}
c0104e4a:	89 ec                	mov    %ebp,%esp
c0104e4c:	5d                   	pop    %ebp
c0104e4d:	c3                   	ret    

c0104e4e <page2ppn>:
page2ppn(struct Page *page) {
c0104e4e:	55                   	push   %ebp
c0104e4f:	89 e5                	mov    %esp,%ebp
    return page - pages;
c0104e51:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c0104e57:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e5a:	29 d0                	sub    %edx,%eax
c0104e5c:	c1 f8 05             	sar    $0x5,%eax
}
c0104e5f:	5d                   	pop    %ebp
c0104e60:	c3                   	ret    

c0104e61 <page2pa>:
page2pa(struct Page *page) {
c0104e61:	55                   	push   %ebp
c0104e62:	89 e5                	mov    %esp,%ebp
c0104e64:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0104e67:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e6a:	89 04 24             	mov    %eax,(%esp)
c0104e6d:	e8 dc ff ff ff       	call   c0104e4e <page2ppn>
c0104e72:	c1 e0 0c             	shl    $0xc,%eax
}
c0104e75:	89 ec                	mov    %ebp,%esp
c0104e77:	5d                   	pop    %ebp
c0104e78:	c3                   	ret    

c0104e79 <pa2page>:
pa2page(uintptr_t pa) {
c0104e79:	55                   	push   %ebp
c0104e7a:	89 e5                	mov    %esp,%ebp
c0104e7c:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c0104e7f:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e82:	c1 e8 0c             	shr    $0xc,%eax
c0104e85:	89 c2                	mov    %eax,%edx
c0104e87:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0104e8c:	39 c2                	cmp    %eax,%edx
c0104e8e:	72 1c                	jb     c0104eac <pa2page+0x33>
        panic("pa2page called with invalid pa");
c0104e90:	c7 44 24 08 cc cd 10 	movl   $0xc010cdcc,0x8(%esp)
c0104e97:	c0 
c0104e98:	c7 44 24 04 5e 00 00 	movl   $0x5e,0x4(%esp)
c0104e9f:	00 
c0104ea0:	c7 04 24 eb cd 10 c0 	movl   $0xc010cdeb,(%esp)
c0104ea7:	e8 8f be ff ff       	call   c0100d3b <__panic>
    return &pages[PPN(pa)];
c0104eac:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c0104eb2:	8b 45 08             	mov    0x8(%ebp),%eax
c0104eb5:	c1 e8 0c             	shr    $0xc,%eax
c0104eb8:	c1 e0 05             	shl    $0x5,%eax
c0104ebb:	01 d0                	add    %edx,%eax
}
c0104ebd:	89 ec                	mov    %ebp,%esp
c0104ebf:	5d                   	pop    %ebp
c0104ec0:	c3                   	ret    

c0104ec1 <page2kva>:
page2kva(struct Page *page) {
c0104ec1:	55                   	push   %ebp
c0104ec2:	89 e5                	mov    %esp,%ebp
c0104ec4:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c0104ec7:	8b 45 08             	mov    0x8(%ebp),%eax
c0104eca:	89 04 24             	mov    %eax,(%esp)
c0104ecd:	e8 8f ff ff ff       	call   c0104e61 <page2pa>
c0104ed2:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104ed5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104ed8:	c1 e8 0c             	shr    $0xc,%eax
c0104edb:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0104ede:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0104ee3:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0104ee6:	72 23                	jb     c0104f0b <page2kva+0x4a>
c0104ee8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104eeb:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0104eef:	c7 44 24 08 fc cd 10 	movl   $0xc010cdfc,0x8(%esp)
c0104ef6:	c0 
c0104ef7:	c7 44 24 04 65 00 00 	movl   $0x65,0x4(%esp)
c0104efe:	00 
c0104eff:	c7 04 24 eb cd 10 c0 	movl   $0xc010cdeb,(%esp)
c0104f06:	e8 30 be ff ff       	call   c0100d3b <__panic>
c0104f0b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104f0e:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c0104f13:	89 ec                	mov    %ebp,%esp
c0104f15:	5d                   	pop    %ebp
c0104f16:	c3                   	ret    

c0104f17 <pte2page>:
pte2page(pte_t pte) {
c0104f17:	55                   	push   %ebp
c0104f18:	89 e5                	mov    %esp,%ebp
c0104f1a:	83 ec 18             	sub    $0x18,%esp
    if (!(pte & PTE_P)) {
c0104f1d:	8b 45 08             	mov    0x8(%ebp),%eax
c0104f20:	83 e0 01             	and    $0x1,%eax
c0104f23:	85 c0                	test   %eax,%eax
c0104f25:	75 1c                	jne    c0104f43 <pte2page+0x2c>
        panic("pte2page called with invalid pte");
c0104f27:	c7 44 24 08 20 ce 10 	movl   $0xc010ce20,0x8(%esp)
c0104f2e:	c0 
c0104f2f:	c7 44 24 04 70 00 00 	movl   $0x70,0x4(%esp)
c0104f36:	00 
c0104f37:	c7 04 24 eb cd 10 c0 	movl   $0xc010cdeb,(%esp)
c0104f3e:	e8 f8 bd ff ff       	call   c0100d3b <__panic>
    return pa2page(PTE_ADDR(pte));
c0104f43:	8b 45 08             	mov    0x8(%ebp),%eax
c0104f46:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0104f4b:	89 04 24             	mov    %eax,(%esp)
c0104f4e:	e8 26 ff ff ff       	call   c0104e79 <pa2page>
}
c0104f53:	89 ec                	mov    %ebp,%esp
c0104f55:	5d                   	pop    %ebp
c0104f56:	c3                   	ret    

c0104f57 <pde2page>:
pde2page(pde_t pde) {
c0104f57:	55                   	push   %ebp
c0104f58:	89 e5                	mov    %esp,%ebp
c0104f5a:	83 ec 18             	sub    $0x18,%esp
    return pa2page(PDE_ADDR(pde));
c0104f5d:	8b 45 08             	mov    0x8(%ebp),%eax
c0104f60:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0104f65:	89 04 24             	mov    %eax,(%esp)
c0104f68:	e8 0c ff ff ff       	call   c0104e79 <pa2page>
}
c0104f6d:	89 ec                	mov    %ebp,%esp
c0104f6f:	5d                   	pop    %ebp
c0104f70:	c3                   	ret    

c0104f71 <page_ref>:
page_ref(struct Page *page) {
c0104f71:	55                   	push   %ebp
c0104f72:	89 e5                	mov    %esp,%ebp
    return page->ref;
c0104f74:	8b 45 08             	mov    0x8(%ebp),%eax
c0104f77:	8b 00                	mov    (%eax),%eax
}
c0104f79:	5d                   	pop    %ebp
c0104f7a:	c3                   	ret    

c0104f7b <set_page_ref>:
set_page_ref(struct Page *page, int val) {
c0104f7b:	55                   	push   %ebp
c0104f7c:	89 e5                	mov    %esp,%ebp
    page->ref = val;
c0104f7e:	8b 45 08             	mov    0x8(%ebp),%eax
c0104f81:	8b 55 0c             	mov    0xc(%ebp),%edx
c0104f84:	89 10                	mov    %edx,(%eax)
}
c0104f86:	90                   	nop
c0104f87:	5d                   	pop    %ebp
c0104f88:	c3                   	ret    

c0104f89 <page_ref_inc>:

static inline int
page_ref_inc(struct Page *page) {
c0104f89:	55                   	push   %ebp
c0104f8a:	89 e5                	mov    %esp,%ebp
    page->ref += 1;
c0104f8c:	8b 45 08             	mov    0x8(%ebp),%eax
c0104f8f:	8b 00                	mov    (%eax),%eax
c0104f91:	8d 50 01             	lea    0x1(%eax),%edx
c0104f94:	8b 45 08             	mov    0x8(%ebp),%eax
c0104f97:	89 10                	mov    %edx,(%eax)
    return page->ref;
c0104f99:	8b 45 08             	mov    0x8(%ebp),%eax
c0104f9c:	8b 00                	mov    (%eax),%eax
}
c0104f9e:	5d                   	pop    %ebp
c0104f9f:	c3                   	ret    

c0104fa0 <page_ref_dec>:

static inline int
page_ref_dec(struct Page *page) {
c0104fa0:	55                   	push   %ebp
c0104fa1:	89 e5                	mov    %esp,%ebp
    page->ref -= 1;
c0104fa3:	8b 45 08             	mov    0x8(%ebp),%eax
c0104fa6:	8b 00                	mov    (%eax),%eax
c0104fa8:	8d 50 ff             	lea    -0x1(%eax),%edx
c0104fab:	8b 45 08             	mov    0x8(%ebp),%eax
c0104fae:	89 10                	mov    %edx,(%eax)
    return page->ref;
c0104fb0:	8b 45 08             	mov    0x8(%ebp),%eax
c0104fb3:	8b 00                	mov    (%eax),%eax
}
c0104fb5:	5d                   	pop    %ebp
c0104fb6:	c3                   	ret    

c0104fb7 <__intr_save>:
__intr_save(void) {
c0104fb7:	55                   	push   %ebp
c0104fb8:	89 e5                	mov    %esp,%ebp
c0104fba:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c0104fbd:	9c                   	pushf  
c0104fbe:	58                   	pop    %eax
c0104fbf:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c0104fc2:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c0104fc5:	25 00 02 00 00       	and    $0x200,%eax
c0104fca:	85 c0                	test   %eax,%eax
c0104fcc:	74 0c                	je     c0104fda <__intr_save+0x23>
        intr_disable();
c0104fce:	e8 1e d0 ff ff       	call   c0101ff1 <intr_disable>
        return 1;
c0104fd3:	b8 01 00 00 00       	mov    $0x1,%eax
c0104fd8:	eb 05                	jmp    c0104fdf <__intr_save+0x28>
    return 0;
c0104fda:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104fdf:	89 ec                	mov    %ebp,%esp
c0104fe1:	5d                   	pop    %ebp
c0104fe2:	c3                   	ret    

c0104fe3 <__intr_restore>:
__intr_restore(bool flag) {
c0104fe3:	55                   	push   %ebp
c0104fe4:	89 e5                	mov    %esp,%ebp
c0104fe6:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c0104fe9:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104fed:	74 05                	je     c0104ff4 <__intr_restore+0x11>
        intr_enable();
c0104fef:	e8 f5 cf ff ff       	call   c0101fe9 <intr_enable>
}
c0104ff4:	90                   	nop
c0104ff5:	89 ec                	mov    %ebp,%esp
c0104ff7:	5d                   	pop    %ebp
c0104ff8:	c3                   	ret    

c0104ff9 <lgdt>:
 * data/code segement registers for kernel.
 * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。
 * */
//定义了一个静态内联函数 lgdt，接收一个指向伪描述符（struct pseudodesc）的指针 pd
static inline void
lgdt(struct pseudodesc *pd) {
c0104ff9:	55                   	push   %ebp
c0104ffa:	89 e5                	mov    %esp,%ebp
    //这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针，告诉处理器 GDT 的地址。
    asm volatile ("lgdt (%0)" :: "r" (pd));
c0104ffc:	8b 45 08             	mov    0x8(%ebp),%eax
c0104fff:	0f 01 10             	lgdtl  (%eax)
    asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS（用户数据段）的值移动到 gs 段寄存器。
c0105002:	b8 23 00 00 00       	mov    $0x23,%eax
c0105007:	8e e8                	mov    %eax,%gs
    asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。
c0105009:	b8 23 00 00 00       	mov    $0x23,%eax
c010500e:	8e e0                	mov    %eax,%fs
    asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS（内核数据段）的值移动到 es 段寄存器。
c0105010:	b8 10 00 00 00       	mov    $0x10,%eax
c0105015:	8e c0                	mov    %eax,%es
    asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器
c0105017:	b8 10 00 00 00       	mov    $0x10,%eax
c010501c:	8e d8                	mov    %eax,%ds
    asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器
c010501e:	b8 10 00 00 00       	mov    $0x10,%eax
c0105023:	8e d0                	mov    %eax,%ss
    // reload cs
    //通过 ljmp 指令重新加载代码段寄存器 cs，并跳转到标签 1。
    asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS));
c0105025:	ea 2c 50 10 c0 08 00 	ljmp   $0x8,$0xc010502c
}
c010502c:	90                   	nop
c010502d:	5d                   	pop    %ebp
c010502e:	c3                   	ret    

c010502f <load_esp0>:
 * load_esp0 - 修改默认任务状态段中的 ESP0，以便在从用户态陷入内核态时能够使用不同的内核栈。
 * */
//uintptr_t esp0：这是新的堆栈指针，通常指向内核栈的顶部。
//修改当前任务状态段（TSS）中的 ESP0 值。ESP0 是在从用户态切换到内核态时，CPU 使用的内核栈指针。
void
load_esp0(uintptr_t esp0) {
c010502f:	55                   	push   %ebp
c0105030:	89 e5                	mov    %esp,%ebp
    ts.ts_esp0 = esp0;
c0105032:	8b 45 08             	mov    0x8(%ebp),%eax
c0105035:	a3 c4 3f 1a c0       	mov    %eax,0xc01a3fc4
}
c010503a:	90                   	nop
c010503b:	5d                   	pop    %ebp
c010503c:	c3                   	ret    

c010503d <gdt_init>:

/* gdt_init - initialize the default GDT and TSS */
/* gdt_init - 初始化默认的 GDT 和 TSS */
static void
gdt_init(void) {
c010503d:	55                   	push   %ebp
c010503e:	89 e5                	mov    %esp,%ebp
c0105040:	83 ec 14             	sub    $0x14,%esp
    // 设置启动内核栈和默认的 SS0
    // set boot kernel stack and default SS0
    load_esp0((uintptr_t)bootstacktop);
c0105043:	b8 00 f0 12 c0       	mov    $0xc012f000,%eax
c0105048:	89 04 24             	mov    %eax,(%esp)
c010504b:	e8 df ff ff ff       	call   c010502f <load_esp0>
    ts.ts_ss0 = KERNEL_DS;
c0105050:	66 c7 05 c8 3f 1a c0 	movw   $0x10,0xc01a3fc8
c0105057:	10 00 
    // 初始化 GDT 中的 TSS 字段
    // initialize the TSS filed of the gdt
    gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL);
c0105059:	66 c7 05 48 fa 12 c0 	movw   $0x68,0xc012fa48
c0105060:	68 00 
c0105062:	b8 c0 3f 1a c0       	mov    $0xc01a3fc0,%eax
c0105067:	0f b7 c0             	movzwl %ax,%eax
c010506a:	66 a3 4a fa 12 c0    	mov    %ax,0xc012fa4a
c0105070:	b8 c0 3f 1a c0       	mov    $0xc01a3fc0,%eax
c0105075:	c1 e8 10             	shr    $0x10,%eax
c0105078:	a2 4c fa 12 c0       	mov    %al,0xc012fa4c
c010507d:	0f b6 05 4d fa 12 c0 	movzbl 0xc012fa4d,%eax
c0105084:	24 f0                	and    $0xf0,%al
c0105086:	0c 09                	or     $0x9,%al
c0105088:	a2 4d fa 12 c0       	mov    %al,0xc012fa4d
c010508d:	0f b6 05 4d fa 12 c0 	movzbl 0xc012fa4d,%eax
c0105094:	24 ef                	and    $0xef,%al
c0105096:	a2 4d fa 12 c0       	mov    %al,0xc012fa4d
c010509b:	0f b6 05 4d fa 12 c0 	movzbl 0xc012fa4d,%eax
c01050a2:	24 9f                	and    $0x9f,%al
c01050a4:	a2 4d fa 12 c0       	mov    %al,0xc012fa4d
c01050a9:	0f b6 05 4d fa 12 c0 	movzbl 0xc012fa4d,%eax
c01050b0:	0c 80                	or     $0x80,%al
c01050b2:	a2 4d fa 12 c0       	mov    %al,0xc012fa4d
c01050b7:	0f b6 05 4e fa 12 c0 	movzbl 0xc012fa4e,%eax
c01050be:	24 f0                	and    $0xf0,%al
c01050c0:	a2 4e fa 12 c0       	mov    %al,0xc012fa4e
c01050c5:	0f b6 05 4e fa 12 c0 	movzbl 0xc012fa4e,%eax
c01050cc:	24 ef                	and    $0xef,%al
c01050ce:	a2 4e fa 12 c0       	mov    %al,0xc012fa4e
c01050d3:	0f b6 05 4e fa 12 c0 	movzbl 0xc012fa4e,%eax
c01050da:	24 df                	and    $0xdf,%al
c01050dc:	a2 4e fa 12 c0       	mov    %al,0xc012fa4e
c01050e1:	0f b6 05 4e fa 12 c0 	movzbl 0xc012fa4e,%eax
c01050e8:	0c 40                	or     $0x40,%al
c01050ea:	a2 4e fa 12 c0       	mov    %al,0xc012fa4e
c01050ef:	0f b6 05 4e fa 12 c0 	movzbl 0xc012fa4e,%eax
c01050f6:	24 7f                	and    $0x7f,%al
c01050f8:	a2 4e fa 12 c0       	mov    %al,0xc012fa4e
c01050fd:	b8 c0 3f 1a c0       	mov    $0xc01a3fc0,%eax
c0105102:	c1 e8 18             	shr    $0x18,%eax
c0105105:	a2 4f fa 12 c0       	mov    %al,0xc012fa4f
    // 使用lgdt加载全局描述符表，更新所有段寄存器
    // reload all segment registers
    lgdt(&gdt_pd);
c010510a:	c7 04 24 50 fa 12 c0 	movl   $0xc012fa50,(%esp)
c0105111:	e8 e3 fe ff ff       	call   c0104ff9 <lgdt>
c0105116:	66 c7 45 fe 28 00    	movw   $0x28,-0x2(%ebp)
    asm volatile ("ltr %0" :: "r" (sel) : "memory");
c010511c:	0f b7 45 fe          	movzwl -0x2(%ebp),%eax
c0105120:	0f 00 d8             	ltr    %ax
}
c0105123:	90                   	nop
    // 加载 TSS，使 CPU 在进行特权级切换时能够正确使用 TSS。
    // load the TSS
    ltr(GD_TSS);
}
c0105124:	90                   	nop
c0105125:	89 ec                	mov    %ebp,%esp
c0105127:	5d                   	pop    %ebp
c0105128:	c3                   	ret    

c0105129 <init_pmm_manager>:

//init_pmm_manager - initialize a pmm_manager instance
//初始化一个 pmm_manager 实例
static void
init_pmm_manager(void) {
c0105129:	55                   	push   %ebp
c010512a:	89 e5                	mov    %esp,%ebp
c010512c:	83 ec 18             	sub    $0x18,%esp
    //将 pmm_manager 指向默认的 PMM 管理器实例。
    pmm_manager = &default_pmm_manager;
c010512f:	c7 05 ac 3f 1a c0 c0 	movl   $0xc010ccc0,0xc01a3fac
c0105136:	cc 10 c0 
     //使用 cprintf 打印当前内存管理器的名称。
    cprintf("memory management: %s\n", pmm_manager->name);
c0105139:	a1 ac 3f 1a c0       	mov    0xc01a3fac,%eax
c010513e:	8b 00                	mov    (%eax),%eax
c0105140:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105144:	c7 04 24 4c ce 10 c0 	movl   $0xc010ce4c,(%esp)
c010514b:	e8 28 b2 ff ff       	call   c0100378 <cprintf>
    //调用 PMM 管理器的初始化函数，以设置和准备内存管理的相关数据结构。
    pmm_manager->init();
c0105150:	a1 ac 3f 1a c0       	mov    0xc01a3fac,%eax
c0105155:	8b 40 04             	mov    0x4(%eax),%eax
c0105158:	ff d0                	call   *%eax
}
c010515a:	90                   	nop
c010515b:	89 ec                	mov    %ebp,%esp
c010515d:	5d                   	pop    %ebp
c010515e:	c3                   	ret    

c010515f <init_memmap>:

//init_memmap - call pmm->init_memmap to build Page struct for free memory 
// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构
//struct Page *base：指向内存页的基础地址。 size_t n：要初始化的页数。 
static void
init_memmap(struct Page *base, size_t n) {
c010515f:	55                   	push   %ebp
c0105160:	89 e5                	mov    %esp,%ebp
c0105162:	83 ec 18             	sub    $0x18,%esp
    pmm_manager->init_memmap(base, n);
c0105165:	a1 ac 3f 1a c0       	mov    0xc01a3fac,%eax
c010516a:	8b 40 08             	mov    0x8(%eax),%eax
c010516d:	8b 55 0c             	mov    0xc(%ebp),%edx
c0105170:	89 54 24 04          	mov    %edx,0x4(%esp)
c0105174:	8b 55 08             	mov    0x8(%ebp),%edx
c0105177:	89 14 24             	mov    %edx,(%esp)
c010517a:	ff d0                	call   *%eax
}
c010517c:	90                   	nop
c010517d:	89 ec                	mov    %ebp,%esp
c010517f:	5d                   	pop    %ebp
c0105180:	c3                   	ret    

c0105181 <alloc_pages>:

//alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory 
// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存
struct Page *
alloc_pages(size_t n) {
c0105181:	55                   	push   %ebp
c0105182:	89 e5                	mov    %esp,%ebp
c0105184:	83 ec 28             	sub    $0x28,%esp
    struct Page *page=NULL;
c0105187:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    bool intr_flag;
    //使用 local_intr_save 保存当前的中断状态，以避免在分配内存时发生中断。    
    while (1)
    {
         local_intr_save(intr_flag);
c010518e:	e8 24 fe ff ff       	call   c0104fb7 <__intr_save>
c0105193:	89 45 f0             	mov    %eax,-0x10(%ebp)
         {
              page = pmm_manager->alloc_pages(n);//尝试分配 n 个页面。
c0105196:	a1 ac 3f 1a c0       	mov    0xc01a3fac,%eax
c010519b:	8b 40 0c             	mov    0xc(%eax),%eax
c010519e:	8b 55 08             	mov    0x8(%ebp),%edx
c01051a1:	89 14 24             	mov    %edx,(%esp)
c01051a4:	ff d0                	call   *%eax
c01051a6:	89 45 f4             	mov    %eax,-0xc(%ebp)
         }
         local_intr_restore(intr_flag);
c01051a9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01051ac:	89 04 24             	mov    %eax,(%esp)
c01051af:	e8 2f fe ff ff       	call   c0104fe3 <__intr_restore>

         if (page != NULL || n > 1 || swap_init_ok == 0) break;
c01051b4:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01051b8:	75 2d                	jne    c01051e7 <alloc_pages+0x66>
c01051ba:	83 7d 08 01          	cmpl   $0x1,0x8(%ebp)
c01051be:	77 27                	ja     c01051e7 <alloc_pages+0x66>
c01051c0:	a1 44 40 1a c0       	mov    0xc01a4044,%eax
c01051c5:	85 c0                	test   %eax,%eax
c01051c7:	74 1e                	je     c01051e7 <alloc_pages+0x66>
         
         extern struct mm_struct *check_mm_struct;
         //cprintf("page %x, call swap_out in alloc_pages %d\n",page, n);
         swap_out(check_mm_struct, n, 0);
c01051c9:	8b 55 08             	mov    0x8(%ebp),%edx
c01051cc:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c01051d1:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01051d8:	00 
c01051d9:	89 54 24 04          	mov    %edx,0x4(%esp)
c01051dd:	89 04 24             	mov    %eax,(%esp)
c01051e0:	e8 38 1d 00 00       	call   c0106f1d <swap_out>
    {
c01051e5:	eb a7                	jmp    c010518e <alloc_pages+0xd>
    }
    //cprintf("n %d,get page %x, No %d in alloc_pages\n",n,page,(page-pages));
    return page;
c01051e7:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01051ea:	89 ec                	mov    %ebp,%esp
c01051ec:	5d                   	pop    %ebp
c01051ed:	c3                   	ret    

c01051ee <free_pages>:

//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory 
// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存
//struct Page *base：指向要释放的内存页的基础地址。size_t n：要释放的页数。
void
free_pages(struct Page *base, size_t n) {
c01051ee:	55                   	push   %ebp
c01051ef:	89 e5                	mov    %esp,%ebp
c01051f1:	83 ec 28             	sub    $0x28,%esp
    bool intr_flag;
    //使用 local_intr_save 保存当前的中断状态，以避免在释放内存时发生中断。
    local_intr_save(intr_flag);
c01051f4:	e8 be fd ff ff       	call   c0104fb7 <__intr_save>
c01051f9:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        //调用物理内存管理器的 free_pages 函数释放 n 页的内存。
        pmm_manager->free_pages(base, n);
c01051fc:	a1 ac 3f 1a c0       	mov    0xc01a3fac,%eax
c0105201:	8b 40 10             	mov    0x10(%eax),%eax
c0105204:	8b 55 0c             	mov    0xc(%ebp),%edx
c0105207:	89 54 24 04          	mov    %edx,0x4(%esp)
c010520b:	8b 55 08             	mov    0x8(%ebp),%edx
c010520e:	89 14 24             	mov    %edx,(%esp)
c0105211:	ff d0                	call   *%eax
    }
    local_intr_restore(intr_flag);
c0105213:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105216:	89 04 24             	mov    %eax,(%esp)
c0105219:	e8 c5 fd ff ff       	call   c0104fe3 <__intr_restore>
}
c010521e:	90                   	nop
c010521f:	89 ec                	mov    %ebp,%esp
c0105221:	5d                   	pop    %ebp
c0105222:	c3                   	ret    

c0105223 <nr_free_pages>:

//nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) 
//of current free memory
// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE)
size_t
nr_free_pages(void) {
c0105223:	55                   	push   %ebp
c0105224:	89 e5                	mov    %esp,%ebp
c0105226:	83 ec 28             	sub    $0x28,%esp
    size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小
    bool intr_flag;// 定义变量 intr_flag 用于保存中断状态
    local_intr_save(intr_flag);// 保存当前中断状态，并禁用中断
c0105229:	e8 89 fd ff ff       	call   c0104fb7 <__intr_save>
c010522e:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数
c0105231:	a1 ac 3f 1a c0       	mov    0xc01a3fac,%eax
c0105236:	8b 40 14             	mov    0x14(%eax),%eax
c0105239:	ff d0                	call   *%eax
c010523b:	89 45 f0             	mov    %eax,-0x10(%ebp)
    }
    local_intr_restore(intr_flag);// 恢复之前保存的中断状态
c010523e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105241:	89 04 24             	mov    %eax,(%esp)
c0105244:	e8 9a fd ff ff       	call   c0104fe3 <__intr_restore>
    return ret;// 返回空闲内存的大小
c0105249:	8b 45 f0             	mov    -0x10(%ebp),%eax
}
c010524c:	89 ec                	mov    %ebp,%esp
c010524e:	5d                   	pop    %ebp
c010524f:	c3                   	ret    

c0105250 <page_init>:

/* pmm_init - initialize the physical memory management */
/* pmm_init - 初始化物理内存管理 */
static void
page_init(void) {
c0105250:	55                   	push   %ebp
c0105251:	89 e5                	mov    %esp,%ebp
c0105253:	57                   	push   %edi
c0105254:	56                   	push   %esi
c0105255:	53                   	push   %ebx
c0105256:	81 ec 9c 00 00 00    	sub    $0x9c,%esp
    // 获取物理内存映射信息，存于特定地址
    struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE);
c010525c:	c7 45 c4 00 80 00 c0 	movl   $0xc0008000,-0x3c(%ebp)
    uint64_t maxpa = 0;// 初始化最大物理地址为0
c0105263:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
c010526a:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
    
    cprintf("e820map:\n");// 打印“e820map”标题
c0105271:	c7 04 24 63 ce 10 c0 	movl   $0xc010ce63,(%esp)
c0105278:	e8 fb b0 ff ff       	call   c0100378 <cprintf>
    int i;
    for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组
c010527d:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c0105284:	e9 0c 01 00 00       	jmp    c0105395 <page_init+0x145>
        uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址
c0105289:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c010528c:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010528f:	89 d0                	mov    %edx,%eax
c0105291:	c1 e0 02             	shl    $0x2,%eax
c0105294:	01 d0                	add    %edx,%eax
c0105296:	c1 e0 02             	shl    $0x2,%eax
c0105299:	01 c8                	add    %ecx,%eax
c010529b:	8b 50 08             	mov    0x8(%eax),%edx
c010529e:	8b 40 04             	mov    0x4(%eax),%eax
c01052a1:	89 45 a0             	mov    %eax,-0x60(%ebp)
c01052a4:	89 55 a4             	mov    %edx,-0x5c(%ebp)
c01052a7:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01052aa:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01052ad:	89 d0                	mov    %edx,%eax
c01052af:	c1 e0 02             	shl    $0x2,%eax
c01052b2:	01 d0                	add    %edx,%eax
c01052b4:	c1 e0 02             	shl    $0x2,%eax
c01052b7:	01 c8                	add    %ecx,%eax
c01052b9:	8b 48 0c             	mov    0xc(%eax),%ecx
c01052bc:	8b 58 10             	mov    0x10(%eax),%ebx
c01052bf:	8b 45 a0             	mov    -0x60(%ebp),%eax
c01052c2:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c01052c5:	01 c8                	add    %ecx,%eax
c01052c7:	11 da                	adc    %ebx,%edx
c01052c9:	89 45 98             	mov    %eax,-0x68(%ebp)
c01052cc:	89 55 9c             	mov    %edx,-0x64(%ebp)
        cprintf("  memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息
c01052cf:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01052d2:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01052d5:	89 d0                	mov    %edx,%eax
c01052d7:	c1 e0 02             	shl    $0x2,%eax
c01052da:	01 d0                	add    %edx,%eax
c01052dc:	c1 e0 02             	shl    $0x2,%eax
c01052df:	01 c8                	add    %ecx,%eax
c01052e1:	83 c0 14             	add    $0x14,%eax
c01052e4:	8b 00                	mov    (%eax),%eax
c01052e6:	89 85 7c ff ff ff    	mov    %eax,-0x84(%ebp)
c01052ec:	8b 45 98             	mov    -0x68(%ebp),%eax
c01052ef:	8b 55 9c             	mov    -0x64(%ebp),%edx
c01052f2:	83 c0 ff             	add    $0xffffffff,%eax
c01052f5:	83 d2 ff             	adc    $0xffffffff,%edx
c01052f8:	89 c6                	mov    %eax,%esi
c01052fa:	89 d7                	mov    %edx,%edi
c01052fc:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01052ff:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0105302:	89 d0                	mov    %edx,%eax
c0105304:	c1 e0 02             	shl    $0x2,%eax
c0105307:	01 d0                	add    %edx,%eax
c0105309:	c1 e0 02             	shl    $0x2,%eax
c010530c:	01 c8                	add    %ecx,%eax
c010530e:	8b 48 0c             	mov    0xc(%eax),%ecx
c0105311:	8b 58 10             	mov    0x10(%eax),%ebx
c0105314:	8b 85 7c ff ff ff    	mov    -0x84(%ebp),%eax
c010531a:	89 44 24 1c          	mov    %eax,0x1c(%esp)
c010531e:	89 74 24 14          	mov    %esi,0x14(%esp)
c0105322:	89 7c 24 18          	mov    %edi,0x18(%esp)
c0105326:	8b 45 a0             	mov    -0x60(%ebp),%eax
c0105329:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c010532c:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105330:	89 54 24 10          	mov    %edx,0x10(%esp)
c0105334:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c0105338:	89 5c 24 08          	mov    %ebx,0x8(%esp)
c010533c:	c7 04 24 70 ce 10 c0 	movl   $0xc010ce70,(%esp)
c0105343:	e8 30 b0 ff ff       	call   c0100378 <cprintf>
                memmap->map[i].size, begin, end - 1, memmap->map[i].type);
        if (memmap->map[i].type == E820_ARM) {// 检查内存类型是否为可用内存
c0105348:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c010534b:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010534e:	89 d0                	mov    %edx,%eax
c0105350:	c1 e0 02             	shl    $0x2,%eax
c0105353:	01 d0                	add    %edx,%eax
c0105355:	c1 e0 02             	shl    $0x2,%eax
c0105358:	01 c8                	add    %ecx,%eax
c010535a:	83 c0 14             	add    $0x14,%eax
c010535d:	8b 00                	mov    (%eax),%eax
c010535f:	83 f8 01             	cmp    $0x1,%eax
c0105362:	75 2e                	jne    c0105392 <page_init+0x142>
            if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内
c0105364:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105367:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010536a:	3b 45 98             	cmp    -0x68(%ebp),%eax
c010536d:	89 d0                	mov    %edx,%eax
c010536f:	1b 45 9c             	sbb    -0x64(%ebp),%eax
c0105372:	73 1e                	jae    c0105392 <page_init+0x142>
c0105374:	ba ff ff ff 37       	mov    $0x37ffffff,%edx
c0105379:	b8 00 00 00 00       	mov    $0x0,%eax
c010537e:	3b 55 a0             	cmp    -0x60(%ebp),%edx
c0105381:	1b 45 a4             	sbb    -0x5c(%ebp),%eax
c0105384:	72 0c                	jb     c0105392 <page_init+0x142>
                maxpa = end;// 更新最大物理地址
c0105386:	8b 45 98             	mov    -0x68(%ebp),%eax
c0105389:	8b 55 9c             	mov    -0x64(%ebp),%edx
c010538c:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010538f:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组
c0105392:	ff 45 dc             	incl   -0x24(%ebp)
c0105395:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0105398:	8b 00                	mov    (%eax),%eax
c010539a:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c010539d:	0f 8c e6 fe ff ff    	jl     c0105289 <page_init+0x39>
            }
        }
    }
    if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限
c01053a3:	ba 00 00 00 38       	mov    $0x38000000,%edx
c01053a8:	b8 00 00 00 00       	mov    $0x0,%eax
c01053ad:	3b 55 e0             	cmp    -0x20(%ebp),%edx
c01053b0:	1b 45 e4             	sbb    -0x1c(%ebp),%eax
c01053b3:	73 0e                	jae    c01053c3 <page_init+0x173>
        maxpa = KMEMSIZE;// 将其限制为内存上限
c01053b5:	c7 45 e0 00 00 00 38 	movl   $0x38000000,-0x20(%ebp)
c01053bc:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
    }

    extern char end[];// 引入全局变量 end，指向内存的结束位置

    npage = maxpa / PGSIZE;// 计算可用页数
c01053c3:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01053c6:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01053c9:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c01053cd:	c1 ea 0c             	shr    $0xc,%edx
c01053d0:	a3 a4 3f 1a c0       	mov    %eax,0xc01a3fa4
    pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界，指向页结构数组的开头
c01053d5:	c7 45 c0 00 10 00 00 	movl   $0x1000,-0x40(%ebp)
c01053dc:	b8 54 61 1a c0       	mov    $0xc01a6154,%eax
c01053e1:	8d 50 ff             	lea    -0x1(%eax),%edx
c01053e4:	8b 45 c0             	mov    -0x40(%ebp),%eax
c01053e7:	01 d0                	add    %edx,%eax
c01053e9:	89 45 bc             	mov    %eax,-0x44(%ebp)
c01053ec:	8b 45 bc             	mov    -0x44(%ebp),%eax
c01053ef:	ba 00 00 00 00       	mov    $0x0,%edx
c01053f4:	f7 75 c0             	divl   -0x40(%ebp)
c01053f7:	8b 45 bc             	mov    -0x44(%ebp),%eax
c01053fa:	29 d0                	sub    %edx,%eax
c01053fc:	a3 a0 3f 1a c0       	mov    %eax,0xc01a3fa0

    for (i = 0; i < npage; i ++) {// 遍历每一页
c0105401:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c0105408:	eb 28                	jmp    c0105432 <page_init+0x1e2>
        SetPageReserved(pages + i);// 将每一页标记为保留状态
c010540a:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c0105410:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0105413:	c1 e0 05             	shl    $0x5,%eax
c0105416:	01 d0                	add    %edx,%eax
c0105418:	83 c0 04             	add    $0x4,%eax
c010541b:	c7 45 94 00 00 00 00 	movl   $0x0,-0x6c(%ebp)
c0105422:	89 45 90             	mov    %eax,-0x70(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0105425:	8b 45 90             	mov    -0x70(%ebp),%eax
c0105428:	8b 55 94             	mov    -0x6c(%ebp),%edx
c010542b:	0f ab 10             	bts    %edx,(%eax)
}
c010542e:	90                   	nop
    for (i = 0; i < npage; i ++) {// 遍历每一页
c010542f:	ff 45 dc             	incl   -0x24(%ebp)
c0105432:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0105435:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c010543a:	39 c2                	cmp    %eax,%edx
c010543c:	72 cc                	jb     c010540a <page_init+0x1ba>
    }

    uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址
c010543e:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0105443:	c1 e0 05             	shl    $0x5,%eax
c0105446:	89 c2                	mov    %eax,%edx
c0105448:	a1 a0 3f 1a c0       	mov    0xc01a3fa0,%eax
c010544d:	01 d0                	add    %edx,%eax
c010544f:	89 45 b8             	mov    %eax,-0x48(%ebp)
c0105452:	81 7d b8 ff ff ff bf 	cmpl   $0xbfffffff,-0x48(%ebp)
c0105459:	77 23                	ja     c010547e <page_init+0x22e>
c010545b:	8b 45 b8             	mov    -0x48(%ebp),%eax
c010545e:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105462:	c7 44 24 08 a0 ce 10 	movl   $0xc010cea0,0x8(%esp)
c0105469:	c0 
c010546a:	c7 44 24 04 1a 01 00 	movl   $0x11a,0x4(%esp)
c0105471:	00 
c0105472:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105479:	e8 bd b8 ff ff       	call   c0100d3b <__panic>
c010547e:	8b 45 b8             	mov    -0x48(%ebp),%eax
c0105481:	05 00 00 00 40       	add    $0x40000000,%eax
c0105486:	89 45 b4             	mov    %eax,-0x4c(%ebp)

    for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射
c0105489:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c0105490:	e9 53 01 00 00       	jmp    c01055e8 <page_init+0x398>
        uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址
c0105495:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0105498:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010549b:	89 d0                	mov    %edx,%eax
c010549d:	c1 e0 02             	shl    $0x2,%eax
c01054a0:	01 d0                	add    %edx,%eax
c01054a2:	c1 e0 02             	shl    $0x2,%eax
c01054a5:	01 c8                	add    %ecx,%eax
c01054a7:	8b 50 08             	mov    0x8(%eax),%edx
c01054aa:	8b 40 04             	mov    0x4(%eax),%eax
c01054ad:	89 45 d0             	mov    %eax,-0x30(%ebp)
c01054b0:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c01054b3:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01054b6:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01054b9:	89 d0                	mov    %edx,%eax
c01054bb:	c1 e0 02             	shl    $0x2,%eax
c01054be:	01 d0                	add    %edx,%eax
c01054c0:	c1 e0 02             	shl    $0x2,%eax
c01054c3:	01 c8                	add    %ecx,%eax
c01054c5:	8b 48 0c             	mov    0xc(%eax),%ecx
c01054c8:	8b 58 10             	mov    0x10(%eax),%ebx
c01054cb:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01054ce:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01054d1:	01 c8                	add    %ecx,%eax
c01054d3:	11 da                	adc    %ebx,%edx
c01054d5:	89 45 c8             	mov    %eax,-0x38(%ebp)
c01054d8:	89 55 cc             	mov    %edx,-0x34(%ebp)
        if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存
c01054db:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01054de:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01054e1:	89 d0                	mov    %edx,%eax
c01054e3:	c1 e0 02             	shl    $0x2,%eax
c01054e6:	01 d0                	add    %edx,%eax
c01054e8:	c1 e0 02             	shl    $0x2,%eax
c01054eb:	01 c8                	add    %ecx,%eax
c01054ed:	83 c0 14             	add    $0x14,%eax
c01054f0:	8b 00                	mov    (%eax),%eax
c01054f2:	83 f8 01             	cmp    $0x1,%eax
c01054f5:	0f 85 ea 00 00 00    	jne    c01055e5 <page_init+0x395>
            if (begin < freemem) {// 如果起始地址小于可用内存地址
c01054fb:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c01054fe:	ba 00 00 00 00       	mov    $0x0,%edx
c0105503:	8b 4d d4             	mov    -0x2c(%ebp),%ecx
c0105506:	39 45 d0             	cmp    %eax,-0x30(%ebp)
c0105509:	19 d1                	sbb    %edx,%ecx
c010550b:	73 0d                	jae    c010551a <page_init+0x2ca>
                begin = freemem;//将起始地址设置为可用内存地址
c010550d:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0105510:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0105513:	c7 45 d4 00 00 00 00 	movl   $0x0,-0x2c(%ebp)
            }
            if (end > KMEMSIZE) {// 如果结束地址超过内存上限
c010551a:	ba 00 00 00 38       	mov    $0x38000000,%edx
c010551f:	b8 00 00 00 00       	mov    $0x0,%eax
c0105524:	3b 55 c8             	cmp    -0x38(%ebp),%edx
c0105527:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c010552a:	73 0e                	jae    c010553a <page_init+0x2ea>
                end = KMEMSIZE;// 将其限制为内存上限
c010552c:	c7 45 c8 00 00 00 38 	movl   $0x38000000,-0x38(%ebp)
c0105533:	c7 45 cc 00 00 00 00 	movl   $0x0,-0x34(%ebp)
            }
            if (begin < end) {// 如果起始地址小于结束地址
c010553a:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010553d:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0105540:	3b 45 c8             	cmp    -0x38(%ebp),%eax
c0105543:	89 d0                	mov    %edx,%eax
c0105545:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c0105548:	0f 83 97 00 00 00    	jae    c01055e5 <page_init+0x395>
                begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界
c010554e:	c7 45 b0 00 10 00 00 	movl   $0x1000,-0x50(%ebp)
c0105555:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0105558:	8b 45 b0             	mov    -0x50(%ebp),%eax
c010555b:	01 d0                	add    %edx,%eax
c010555d:	48                   	dec    %eax
c010555e:	89 45 ac             	mov    %eax,-0x54(%ebp)
c0105561:	8b 45 ac             	mov    -0x54(%ebp),%eax
c0105564:	ba 00 00 00 00       	mov    $0x0,%edx
c0105569:	f7 75 b0             	divl   -0x50(%ebp)
c010556c:	8b 45 ac             	mov    -0x54(%ebp),%eax
c010556f:	29 d0                	sub    %edx,%eax
c0105571:	ba 00 00 00 00       	mov    $0x0,%edx
c0105576:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0105579:	89 55 d4             	mov    %edx,-0x2c(%ebp)
                end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界
c010557c:	8b 45 c8             	mov    -0x38(%ebp),%eax
c010557f:	89 45 a8             	mov    %eax,-0x58(%ebp)
c0105582:	8b 45 a8             	mov    -0x58(%ebp),%eax
c0105585:	ba 00 00 00 00       	mov    $0x0,%edx
c010558a:	89 c7                	mov    %eax,%edi
c010558c:	81 e7 00 f0 ff ff    	and    $0xfffff000,%edi
c0105592:	89 7d 80             	mov    %edi,-0x80(%ebp)
c0105595:	89 d0                	mov    %edx,%eax
c0105597:	83 e0 00             	and    $0x0,%eax
c010559a:	89 45 84             	mov    %eax,-0x7c(%ebp)
c010559d:	8b 45 80             	mov    -0x80(%ebp),%eax
c01055a0:	8b 55 84             	mov    -0x7c(%ebp),%edx
c01055a3:	89 45 c8             	mov    %eax,-0x38(%ebp)
c01055a6:	89 55 cc             	mov    %edx,-0x34(%ebp)
                if (begin < end) {// 如果调整后的起始地址仍小于结束地址
c01055a9:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01055ac:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01055af:	3b 45 c8             	cmp    -0x38(%ebp),%eax
c01055b2:	89 d0                	mov    %edx,%eax
c01055b4:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c01055b7:	73 2c                	jae    c01055e5 <page_init+0x395>
                    init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射
c01055b9:	8b 45 c8             	mov    -0x38(%ebp),%eax
c01055bc:	8b 55 cc             	mov    -0x34(%ebp),%edx
c01055bf:	2b 45 d0             	sub    -0x30(%ebp),%eax
c01055c2:	1b 55 d4             	sbb    -0x2c(%ebp),%edx
c01055c5:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c01055c9:	c1 ea 0c             	shr    $0xc,%edx
c01055cc:	89 c3                	mov    %eax,%ebx
c01055ce:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01055d1:	89 04 24             	mov    %eax,(%esp)
c01055d4:	e8 a0 f8 ff ff       	call   c0104e79 <pa2page>
c01055d9:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c01055dd:	89 04 24             	mov    %eax,(%esp)
c01055e0:	e8 7a fb ff ff       	call   c010515f <init_memmap>
    for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射
c01055e5:	ff 45 dc             	incl   -0x24(%ebp)
c01055e8:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c01055eb:	8b 00                	mov    (%eax),%eax
c01055ed:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c01055f0:	0f 8c 9f fe ff ff    	jl     c0105495 <page_init+0x245>
                }
            }
        }
    }
}
c01055f6:	90                   	nop
c01055f7:	90                   	nop
c01055f8:	81 c4 9c 00 00 00    	add    $0x9c,%esp
c01055fe:	5b                   	pop    %ebx
c01055ff:	5e                   	pop    %esi
c0105600:	5f                   	pop    %edi
c0105601:	5d                   	pop    %ebp
c0105602:	c3                   	ret    

c0105603 <boot_map_segment>:
//la:   需要映射的线性地址（经过 x86 段映射后的地址）
//  size: memory size   size: 内存大小
//  pa:   physical address of this memory  pa:该内存的物理地址
//  perm: permission of this memory    perm: 该内存的权限
static void
boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) {
c0105603:	55                   	push   %ebp
c0105604:	89 e5                	mov    %esp,%ebp
c0105606:	83 ec 38             	sub    $0x38,%esp
    // 确保线性地址和物理地址的页偏移相同
    assert(PGOFF(la) == PGOFF(pa));
c0105609:	8b 45 0c             	mov    0xc(%ebp),%eax
c010560c:	33 45 14             	xor    0x14(%ebp),%eax
c010560f:	25 ff 0f 00 00       	and    $0xfff,%eax
c0105614:	85 c0                	test   %eax,%eax
c0105616:	74 24                	je     c010563c <boot_map_segment+0x39>
c0105618:	c7 44 24 0c d2 ce 10 	movl   $0xc010ced2,0xc(%esp)
c010561f:	c0 
c0105620:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105627:	c0 
c0105628:	c7 44 24 04 3b 01 00 	movl   $0x13b,0x4(%esp)
c010562f:	00 
c0105630:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105637:	e8 ff b6 ff ff       	call   c0100d3b <__panic>
    // 计算需要映射的页数，ROUNDUP 将总大小对齐到下一个页大小的边界
    size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE;
c010563c:	c7 45 f0 00 10 00 00 	movl   $0x1000,-0x10(%ebp)
c0105643:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105646:	25 ff 0f 00 00       	and    $0xfff,%eax
c010564b:	89 c2                	mov    %eax,%edx
c010564d:	8b 45 10             	mov    0x10(%ebp),%eax
c0105650:	01 c2                	add    %eax,%edx
c0105652:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105655:	01 d0                	add    %edx,%eax
c0105657:	48                   	dec    %eax
c0105658:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010565b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010565e:	ba 00 00 00 00       	mov    $0x0,%edx
c0105663:	f7 75 f0             	divl   -0x10(%ebp)
c0105666:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0105669:	29 d0                	sub    %edx,%eax
c010566b:	c1 e8 0c             	shr    $0xc,%eax
c010566e:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 将线性地址向下对齐到页边界
    la = ROUNDDOWN(la, PGSIZE);
c0105671:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105674:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0105677:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010567a:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010567f:	89 45 0c             	mov    %eax,0xc(%ebp)
    // 将物理地址向下对齐到页边界
    pa = ROUNDDOWN(pa, PGSIZE);
c0105682:	8b 45 14             	mov    0x14(%ebp),%eax
c0105685:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0105688:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010568b:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0105690:	89 45 14             	mov    %eax,0x14(%ebp)
    // 循环遍历每一页，直到映射的页数为零
    for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) {
c0105693:	eb 68                	jmp    c01056fd <boot_map_segment+0xfa>
        // 获取当前页的页表项指针，如果不存在则创建新的页表项
        pte_t *ptep = get_pte(pgdir, la, 1);
c0105695:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c010569c:	00 
c010569d:	8b 45 0c             	mov    0xc(%ebp),%eax
c01056a0:	89 44 24 04          	mov    %eax,0x4(%esp)
c01056a4:	8b 45 08             	mov    0x8(%ebp),%eax
c01056a7:	89 04 24             	mov    %eax,(%esp)
c01056aa:	e8 8d 01 00 00       	call   c010583c <get_pte>
c01056af:	89 45 e0             	mov    %eax,-0x20(%ebp)
        // 确保页表项指针不为空
        assert(ptep != NULL);
c01056b2:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c01056b6:	75 24                	jne    c01056dc <boot_map_segment+0xd9>
c01056b8:	c7 44 24 0c fe ce 10 	movl   $0xc010cefe,0xc(%esp)
c01056bf:	c0 
c01056c0:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01056c7:	c0 
c01056c8:	c7 44 24 04 47 01 00 	movl   $0x147,0x4(%esp)
c01056cf:	00 
c01056d0:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01056d7:	e8 5f b6 ff ff       	call   c0100d3b <__panic>
         // 设置页表项，包含物理地址、存在位和权限
        *ptep = pa | PTE_P | perm;
c01056dc:	8b 45 14             	mov    0x14(%ebp),%eax
c01056df:	0b 45 18             	or     0x18(%ebp),%eax
c01056e2:	83 c8 01             	or     $0x1,%eax
c01056e5:	89 c2                	mov    %eax,%edx
c01056e7:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01056ea:	89 10                	mov    %edx,(%eax)
    for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) {
c01056ec:	ff 4d f4             	decl   -0xc(%ebp)
c01056ef:	81 45 0c 00 10 00 00 	addl   $0x1000,0xc(%ebp)
c01056f6:	81 45 14 00 10 00 00 	addl   $0x1000,0x14(%ebp)
c01056fd:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105701:	75 92                	jne    c0105695 <boot_map_segment+0x92>
    }
}
c0105703:	90                   	nop
c0105704:	90                   	nop
c0105705:	89 ec                	mov    %ebp,%esp
c0105707:	5d                   	pop    %ebp
c0105708:	c3                   	ret    

c0105709 <boot_alloc_page>:
// return value: the kernel virtual address of this allocated page
//note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table)
//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址
//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存
static void *
boot_alloc_page(void) {
c0105709:	55                   	push   %ebp
c010570a:	89 e5                	mov    %esp,%ebp
c010570c:	83 ec 28             	sub    $0x28,%esp
    struct Page *p = alloc_page();// 调用分配页面的函数
c010570f:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0105716:	e8 66 fa ff ff       	call   c0105181 <alloc_pages>
c010571b:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (p == NULL) {// 检查分配是否成功
c010571e:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105722:	75 1c                	jne    c0105740 <boot_alloc_page+0x37>
        panic("boot_alloc_page failed.\n");// 如果分配失败，则触发异常
c0105724:	c7 44 24 08 0b cf 10 	movl   $0xc010cf0b,0x8(%esp)
c010572b:	c0 
c010572c:	c7 44 24 04 56 01 00 	movl   $0x156,0x4(%esp)
c0105733:	00 
c0105734:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c010573b:	e8 fb b5 ff ff       	call   c0100d3b <__panic>
    }
    return page2kva(p);// 返回分配页面的内核虚拟地址
c0105740:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105743:	89 04 24             	mov    %eax,(%esp)
c0105746:	e8 76 f7 ff ff       	call   c0104ec1 <page2kva>
}
c010574b:	89 ec                	mov    %ebp,%esp
c010574d:	5d                   	pop    %ebp
c010574e:	c3                   	ret    

c010574f <pmm_init>:
//pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism 
//         - check the correctness of pmm & paging mechanism, print PDT&PT
//pmm_init - 设置物理内存管理器，构建页目录表(PDT)和页表(PT)，以设置分页机制
//           - 检查物理内存管理器和分页机制的正确性，打印页目录表和页表
void
pmm_init(void) {
c010574f:	55                   	push   %ebp
c0105750:	89 e5                	mov    %esp,%ebp
c0105752:	83 ec 38             	sub    $0x38,%esp
    // We've already enabled paging
    // 我们已经启用了分页
    boot_cr3 = PADDR(boot_pgdir);
c0105755:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c010575a:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010575d:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c0105764:	77 23                	ja     c0105789 <pmm_init+0x3a>
c0105766:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105769:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010576d:	c7 44 24 08 a0 ce 10 	movl   $0xc010cea0,0x8(%esp)
c0105774:	c0 
c0105775:	c7 44 24 04 63 01 00 	movl   $0x163,0x4(%esp)
c010577c:	00 
c010577d:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105784:	e8 b2 b5 ff ff       	call   c0100d3b <__panic>
c0105789:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010578c:	05 00 00 00 40       	add    $0x40000000,%eax
c0105791:	a3 a8 3f 1a c0       	mov    %eax,0xc01a3fa8
     // 我们需要分配/释放物理内存（粒度为 4KB 或其他大小）。
    // 因此在 pmm.h 中定义了物理内存管理器的框架（struct pmm_manager）。
    // 首先，我们应该基于该框架初始化一个物理内存管理器(pmm)。
    // 然后 pmm 可以分配/释放物理内存。
    // 现在，first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。
    init_pmm_manager();// 初始化物理内存管理器
c0105796:	e8 8e f9 ff ff       	call   c0105129 <init_pmm_manager>

    // detect physical memory space, reserve already used memory,
    // then use pmm->init_memmap to create free page list
    // 检测物理内存空间，保留已经使用的内存，
    // 然后使用 pmm->init_memmap 创建空闲页面列表
    page_init();// 初始化页面管理
c010579b:	e8 b0 fa ff ff       	call   c0105250 <page_init>

    //use pmm->check to verify the correctness of the alloc/free function in a pmm
    // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性
    check_alloc_page();// 检查页面分配功能
c01057a0:	e8 ee 08 00 00       	call   c0106093 <check_alloc_page>

    check_pgdir();// 检查页目录的状态
c01057a5:	e8 0a 09 00 00       	call   c01060b4 <check_pgdir>

    // recursively insert boot_pgdir in itself
    // to form a virtual page table at virtual address VPT
    // 递归地将 boot_pgdir 插入到自身中
    // 在虚拟地址 VPT 处形成虚拟页表
    boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项，映射自身
c01057aa:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01057af:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01057b2:	81 7d f0 ff ff ff bf 	cmpl   $0xbfffffff,-0x10(%ebp)
c01057b9:	77 23                	ja     c01057de <pmm_init+0x8f>
c01057bb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01057be:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01057c2:	c7 44 24 08 a0 ce 10 	movl   $0xc010cea0,0x8(%esp)
c01057c9:	c0 
c01057ca:	c7 44 24 04 83 01 00 	movl   $0x183,0x4(%esp)
c01057d1:	00 
c01057d2:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01057d9:	e8 5d b5 ff ff       	call   c0100d3b <__panic>
c01057de:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01057e1:	8d 90 00 00 00 40    	lea    0x40000000(%eax),%edx
c01057e7:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01057ec:	05 ac 0f 00 00       	add    $0xfac,%eax
c01057f1:	83 ca 03             	or     $0x3,%edx
c01057f4:	89 10                	mov    %edx,(%eax)

    // map all physical memory to linear memory with base linear addr KERNBASE
    // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE
    // 将所有物理内存映射到线性内存，基地址为 KERNBASE
    // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE
    boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存
c01057f6:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01057fb:	c7 44 24 10 02 00 00 	movl   $0x2,0x10(%esp)
c0105802:	00 
c0105803:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c010580a:	00 
c010580b:	c7 44 24 08 00 00 00 	movl   $0x38000000,0x8(%esp)
c0105812:	38 
c0105813:	c7 44 24 04 00 00 00 	movl   $0xc0000000,0x4(%esp)
c010581a:	c0 
c010581b:	89 04 24             	mov    %eax,(%esp)
c010581e:	e8 e0 fd ff ff       	call   c0105603 <boot_map_segment>
    // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS
    // 由于我们正在使用引导加载程序的 GDT，
    // 我们应该重新加载 GDT（第二次，也是最后一次），以获取用户段和 TSS
    // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G
    // 然后在 TSS 中设置内核栈 (ss:esp)，在 gdt 中设置 TSS，加载 TSS
    gdt_init();// 初始化全局描述符表
c0105823:	e8 15 f8 ff ff       	call   c010503d <gdt_init>

    //now the basic virtual memory map(see memalyout.h) is established.
    //check the correctness of the basic virtual memory map.
     // 现在基本的虚拟内存映射（见 memlayout.h）已建立。
    // 检查基础虚拟内存映射的正确性。
    check_boot_pgdir(); // 检查页目录的正确性
c0105828:	e8 25 0f 00 00       	call   c0106752 <check_boot_pgdir>

    print_pgdir(); // 打印页目录表
c010582d:	e8 cc 13 00 00       	call   c0106bfe <print_pgdir>
    kmalloc_init();
c0105832:	e8 70 f3 ff ff       	call   c0104ba7 <kmalloc_init>

}
c0105837:	90                   	nop
c0105838:	89 ec                	mov    %ebp,%esp
c010583a:	5d                   	pop    %ebp
c010583b:	c3                   	ret    

c010583c <get_pte>:
//  pgdir:  页目录的内核虚拟基地址
//  la:     需要映射的线性地址
//  create: 一个逻辑值，决定是否为页表分配一页
// 返回值：该 PTE 的内核虚拟地址
pte_t *
get_pte(pde_t *pgdir, uintptr_t la, bool create) {
c010583c:	55                   	push   %ebp
c010583d:	89 e5                	mov    %esp,%ebp
c010583f:	83 ec 38             	sub    $0x38,%esp
                          // (7) set page directory entry's permission
    }
    return NULL;          // (8) return page table entry
#endif
    // (1) 找到页目录项
    pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引
c0105842:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105845:	c1 e8 16             	shr    $0x16,%eax
c0105848:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c010584f:	8b 45 08             	mov    0x8(%ebp),%eax
c0105852:	01 d0                	add    %edx,%eax
c0105854:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // (2) 检查页目录项是否存在
    if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置
c0105857:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010585a:	8b 00                	mov    (%eax),%eax
c010585c:	83 e0 01             	and    $0x1,%eax
c010585f:	85 c0                	test   %eax,%eax
c0105861:	0f 85 af 00 00 00    	jne    c0105916 <get_pte+0xda>
        struct Page *page;// 声明一个指针，用于指向新分配的页面
        // 检查是否允许创建新页表，或者分配页表失败
        if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败
c0105867:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010586b:	74 15                	je     c0105882 <get_pte+0x46>
c010586d:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0105874:	e8 08 f9 ff ff       	call   c0105181 <alloc_pages>
c0105879:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010587c:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0105880:	75 0a                	jne    c010588c <get_pte+0x50>
            return NULL;// 返回 NULL，表示无法获取页表
c0105882:	b8 00 00 00 00       	mov    $0x0,%eax
c0105887:	e9 e7 00 00 00       	jmp    c0105973 <get_pte+0x137>
        }
        // 设置新分配页面的引用计数为 1
        set_page_ref(page, 1);
c010588c:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0105893:	00 
c0105894:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105897:	89 04 24             	mov    %eax,(%esp)
c010589a:	e8 dc f6 ff ff       	call   c0104f7b <set_page_ref>
        uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址
c010589f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01058a2:	89 04 24             	mov    %eax,(%esp)
c01058a5:	e8 b7 f5 ff ff       	call   c0104e61 <page2pa>
c01058aa:	89 45 ec             	mov    %eax,-0x14(%ebp)
        memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容，初始化为零
c01058ad:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01058b0:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01058b3:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01058b6:	c1 e8 0c             	shr    $0xc,%eax
c01058b9:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c01058bc:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c01058c1:	39 45 e4             	cmp    %eax,-0x1c(%ebp)
c01058c4:	72 23                	jb     c01058e9 <get_pte+0xad>
c01058c6:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01058c9:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01058cd:	c7 44 24 08 fc cd 10 	movl   $0xc010cdfc,0x8(%esp)
c01058d4:	c0 
c01058d5:	c7 44 24 04 dd 01 00 	movl   $0x1dd,0x4(%esp)
c01058dc:	00 
c01058dd:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01058e4:	e8 52 b4 ff ff       	call   c0100d3b <__panic>
c01058e9:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01058ec:	2d 00 00 00 40       	sub    $0x40000000,%eax
c01058f1:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c01058f8:	00 
c01058f9:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0105900:	00 
c0105901:	89 04 24             	mov    %eax,(%esp)
c0105904:	e8 e8 64 00 00       	call   c010bdf1 <memset>
        // 更新页目录项，设置物理地址和权限位
        *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位（用户可访问、可写、有效）合并设置
c0105909:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010590c:	83 c8 07             	or     $0x7,%eax
c010590f:	89 c2                	mov    %eax,%edx
c0105911:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105914:	89 10                	mov    %edx,(%eax)
    }
    // 返回指定线性地址 la 对应的页表项的内核虚拟地址
    return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针
c0105916:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105919:	8b 00                	mov    (%eax),%eax
c010591b:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0105920:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0105923:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105926:	c1 e8 0c             	shr    $0xc,%eax
c0105929:	89 45 dc             	mov    %eax,-0x24(%ebp)
c010592c:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0105931:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c0105934:	72 23                	jb     c0105959 <get_pte+0x11d>
c0105936:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105939:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010593d:	c7 44 24 08 fc cd 10 	movl   $0xc010cdfc,0x8(%esp)
c0105944:	c0 
c0105945:	c7 44 24 04 e2 01 00 	movl   $0x1e2,0x4(%esp)
c010594c:	00 
c010594d:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105954:	e8 e2 b3 ff ff       	call   c0100d3b <__panic>
c0105959:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010595c:	2d 00 00 00 40       	sub    $0x40000000,%eax
c0105961:	89 c2                	mov    %eax,%edx
c0105963:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105966:	c1 e8 0c             	shr    $0xc,%eax
c0105969:	25 ff 03 00 00       	and    $0x3ff,%eax
c010596e:	c1 e0 02             	shl    $0x2,%eax
c0105971:	01 d0                	add    %edx,%eax
}
c0105973:	89 ec                	mov    %ebp,%esp
c0105975:	5d                   	pop    %ebp
c0105976:	c3                   	ret    

c0105977 <get_page>:

//get_page - get related Page struct for linear address la using PDT pgdir
// get_page - 获取与线性地址 la 相关的 Page 结构体，使用页目录 pgdir
struct Page *
get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) {
c0105977:	55                   	push   %ebp
c0105978:	89 e5                	mov    %esp,%ebp
c010597a:	83 ec 28             	sub    $0x28,%esp
     // 调用 get_pte 函数获取对应线性地址 la 的页表项指针
    pte_t *ptep = get_pte(pgdir, la, 0);
c010597d:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105984:	00 
c0105985:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105988:	89 44 24 04          	mov    %eax,0x4(%esp)
c010598c:	8b 45 08             	mov    0x8(%ebp),%eax
c010598f:	89 04 24             	mov    %eax,(%esp)
c0105992:	e8 a5 fe ff ff       	call   c010583c <get_pte>
c0105997:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 如果 ptep_store 指针不为 NULL，将 ptep 存储到 ptep_store 指向的位置
    if (ptep_store != NULL) {
c010599a:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010599e:	74 08                	je     c01059a8 <get_page+0x31>
        *ptep_store = ptep; // 存储当前页表项的指针
c01059a0:	8b 45 10             	mov    0x10(%ebp),%eax
c01059a3:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01059a6:	89 10                	mov    %edx,(%eax)
    }
    // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置
    if (ptep != NULL && *ptep & PTE_P) {
c01059a8:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01059ac:	74 1b                	je     c01059c9 <get_page+0x52>
c01059ae:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01059b1:	8b 00                	mov    (%eax),%eax
c01059b3:	83 e0 01             	and    $0x1,%eax
c01059b6:	85 c0                	test   %eax,%eax
c01059b8:	74 0f                	je     c01059c9 <get_page+0x52>
        // 返回与页表项对应的 Page 结构体
        return pte2page(*ptep);// 将页表项转换为对应的 Page 结构
c01059ba:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01059bd:	8b 00                	mov    (%eax),%eax
c01059bf:	89 04 24             	mov    %eax,(%esp)
c01059c2:	e8 50 f5 ff ff       	call   c0104f17 <pte2page>
c01059c7:	eb 05                	jmp    c01059ce <get_page+0x57>
    }
    // 如果未找到有效的页，返回 NULL
    return NULL;
c01059c9:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01059ce:	89 ec                	mov    %ebp,%esp
c01059d0:	5d                   	pop    %ebp
c01059d1:	c3                   	ret    

c01059d2 <page_remove_pte>:

//page_remove_pte - free an Page sturct which is related linear address la
//                - and clean(invalidate) pte which is related linear address la
//note: PT is changed, so the TLB need to be invalidate 
static inline void
page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) {
c01059d2:	55                   	push   %ebp
c01059d3:	89 e5                	mov    %esp,%ebp
c01059d5:	83 ec 28             	sub    $0x28,%esp
                                  //(4) and free this page when page reference reachs 0
                                  //(5) clear second page table entry
                                  //(6) flush tlb
    }
#endif
    if (*ptep & PTE_P) {
c01059d8:	8b 45 10             	mov    0x10(%ebp),%eax
c01059db:	8b 00                	mov    (%eax),%eax
c01059dd:	83 e0 01             	and    $0x1,%eax
c01059e0:	85 c0                	test   %eax,%eax
c01059e2:	74 4d                	je     c0105a31 <page_remove_pte+0x5f>
        struct Page *page = pte2page(*ptep);// 找到对应的物理页
c01059e4:	8b 45 10             	mov    0x10(%ebp),%eax
c01059e7:	8b 00                	mov    (%eax),%eax
c01059e9:	89 04 24             	mov    %eax,(%esp)
c01059ec:	e8 26 f5 ff ff       	call   c0104f17 <pte2page>
c01059f1:	89 45 f4             	mov    %eax,-0xc(%ebp)
        // 减少物理页的引用计数，如果引用计数为零，释放该物理页
        if (page_ref_dec(page) == 0) {
c01059f4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01059f7:	89 04 24             	mov    %eax,(%esp)
c01059fa:	e8 a1 f5 ff ff       	call   c0104fa0 <page_ref_dec>
c01059ff:	85 c0                	test   %eax,%eax
c0105a01:	75 13                	jne    c0105a16 <page_remove_pte+0x44>
            free_page(page);
c0105a03:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0105a0a:	00 
c0105a0b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105a0e:	89 04 24             	mov    %eax,(%esp)
c0105a11:	e8 d8 f7 ff ff       	call   c01051ee <free_pages>
        }
        *ptep = 0;// 清除页表项
c0105a16:	8b 45 10             	mov    0x10(%ebp),%eax
c0105a19:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
        tlb_invalidate(pgdir, la);// 刷新 TLB
c0105a1f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105a22:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105a26:	8b 45 08             	mov    0x8(%ebp),%eax
c0105a29:	89 04 24             	mov    %eax,(%esp)
c0105a2c:	e8 2d 05 00 00       	call   c0105f5e <tlb_invalidate>
    }
}
c0105a31:	90                   	nop
c0105a32:	89 ec                	mov    %ebp,%esp
c0105a34:	5d                   	pop    %ebp
c0105a35:	c3                   	ret    

c0105a36 <unmap_range>:

void
unmap_range(pde_t *pgdir, uintptr_t start, uintptr_t end) {
c0105a36:	55                   	push   %ebp
c0105a37:	89 e5                	mov    %esp,%ebp
c0105a39:	83 ec 28             	sub    $0x28,%esp
    assert(start % PGSIZE == 0 && end % PGSIZE == 0);
c0105a3c:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105a3f:	25 ff 0f 00 00       	and    $0xfff,%eax
c0105a44:	85 c0                	test   %eax,%eax
c0105a46:	75 0c                	jne    c0105a54 <unmap_range+0x1e>
c0105a48:	8b 45 10             	mov    0x10(%ebp),%eax
c0105a4b:	25 ff 0f 00 00       	and    $0xfff,%eax
c0105a50:	85 c0                	test   %eax,%eax
c0105a52:	74 24                	je     c0105a78 <unmap_range+0x42>
c0105a54:	c7 44 24 0c 24 cf 10 	movl   $0xc010cf24,0xc(%esp)
c0105a5b:	c0 
c0105a5c:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105a63:	c0 
c0105a64:	c7 44 24 04 23 02 00 	movl   $0x223,0x4(%esp)
c0105a6b:	00 
c0105a6c:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105a73:	e8 c3 b2 ff ff       	call   c0100d3b <__panic>
    assert(USER_ACCESS(start, end));
c0105a78:	81 7d 0c ff ff 1f 00 	cmpl   $0x1fffff,0xc(%ebp)
c0105a7f:	76 11                	jbe    c0105a92 <unmap_range+0x5c>
c0105a81:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105a84:	3b 45 10             	cmp    0x10(%ebp),%eax
c0105a87:	73 09                	jae    c0105a92 <unmap_range+0x5c>
c0105a89:	81 7d 10 00 00 00 b0 	cmpl   $0xb0000000,0x10(%ebp)
c0105a90:	76 24                	jbe    c0105ab6 <unmap_range+0x80>
c0105a92:	c7 44 24 0c 4d cf 10 	movl   $0xc010cf4d,0xc(%esp)
c0105a99:	c0 
c0105a9a:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105aa1:	c0 
c0105aa2:	c7 44 24 04 24 02 00 	movl   $0x224,0x4(%esp)
c0105aa9:	00 
c0105aaa:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105ab1:	e8 85 b2 ff ff       	call   c0100d3b <__panic>

    do {
        pte_t *ptep = get_pte(pgdir, start, 0);
c0105ab6:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105abd:	00 
c0105abe:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105ac1:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105ac5:	8b 45 08             	mov    0x8(%ebp),%eax
c0105ac8:	89 04 24             	mov    %eax,(%esp)
c0105acb:	e8 6c fd ff ff       	call   c010583c <get_pte>
c0105ad0:	89 45 f4             	mov    %eax,-0xc(%ebp)
        if (ptep == NULL) {
c0105ad3:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105ad7:	75 18                	jne    c0105af1 <unmap_range+0xbb>
            start = ROUNDDOWN(start + PTSIZE, PTSIZE);
c0105ad9:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105adc:	05 00 00 40 00       	add    $0x400000,%eax
c0105ae1:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0105ae4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105ae7:	25 00 00 c0 ff       	and    $0xffc00000,%eax
c0105aec:	89 45 0c             	mov    %eax,0xc(%ebp)
            continue ;
c0105aef:	eb 29                	jmp    c0105b1a <unmap_range+0xe4>
        }
        if (*ptep != 0) {
c0105af1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105af4:	8b 00                	mov    (%eax),%eax
c0105af6:	85 c0                	test   %eax,%eax
c0105af8:	74 19                	je     c0105b13 <unmap_range+0xdd>
            page_remove_pte(pgdir, start, ptep);
c0105afa:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105afd:	89 44 24 08          	mov    %eax,0x8(%esp)
c0105b01:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105b04:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105b08:	8b 45 08             	mov    0x8(%ebp),%eax
c0105b0b:	89 04 24             	mov    %eax,(%esp)
c0105b0e:	e8 bf fe ff ff       	call   c01059d2 <page_remove_pte>
        }
        start += PGSIZE;
c0105b13:	81 45 0c 00 10 00 00 	addl   $0x1000,0xc(%ebp)
    } while (start != 0 && start < end);
c0105b1a:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0105b1e:	74 08                	je     c0105b28 <unmap_range+0xf2>
c0105b20:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105b23:	3b 45 10             	cmp    0x10(%ebp),%eax
c0105b26:	72 8e                	jb     c0105ab6 <unmap_range+0x80>
}
c0105b28:	90                   	nop
c0105b29:	89 ec                	mov    %ebp,%esp
c0105b2b:	5d                   	pop    %ebp
c0105b2c:	c3                   	ret    

c0105b2d <exit_range>:

void
exit_range(pde_t *pgdir, uintptr_t start, uintptr_t end) {
c0105b2d:	55                   	push   %ebp
c0105b2e:	89 e5                	mov    %esp,%ebp
c0105b30:	83 ec 28             	sub    $0x28,%esp
    assert(start % PGSIZE == 0 && end % PGSIZE == 0);
c0105b33:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105b36:	25 ff 0f 00 00       	and    $0xfff,%eax
c0105b3b:	85 c0                	test   %eax,%eax
c0105b3d:	75 0c                	jne    c0105b4b <exit_range+0x1e>
c0105b3f:	8b 45 10             	mov    0x10(%ebp),%eax
c0105b42:	25 ff 0f 00 00       	and    $0xfff,%eax
c0105b47:	85 c0                	test   %eax,%eax
c0105b49:	74 24                	je     c0105b6f <exit_range+0x42>
c0105b4b:	c7 44 24 0c 24 cf 10 	movl   $0xc010cf24,0xc(%esp)
c0105b52:	c0 
c0105b53:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105b5a:	c0 
c0105b5b:	c7 44 24 04 35 02 00 	movl   $0x235,0x4(%esp)
c0105b62:	00 
c0105b63:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105b6a:	e8 cc b1 ff ff       	call   c0100d3b <__panic>
    assert(USER_ACCESS(start, end));
c0105b6f:	81 7d 0c ff ff 1f 00 	cmpl   $0x1fffff,0xc(%ebp)
c0105b76:	76 11                	jbe    c0105b89 <exit_range+0x5c>
c0105b78:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105b7b:	3b 45 10             	cmp    0x10(%ebp),%eax
c0105b7e:	73 09                	jae    c0105b89 <exit_range+0x5c>
c0105b80:	81 7d 10 00 00 00 b0 	cmpl   $0xb0000000,0x10(%ebp)
c0105b87:	76 24                	jbe    c0105bad <exit_range+0x80>
c0105b89:	c7 44 24 0c 4d cf 10 	movl   $0xc010cf4d,0xc(%esp)
c0105b90:	c0 
c0105b91:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105b98:	c0 
c0105b99:	c7 44 24 04 36 02 00 	movl   $0x236,0x4(%esp)
c0105ba0:	00 
c0105ba1:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105ba8:	e8 8e b1 ff ff       	call   c0100d3b <__panic>

    start = ROUNDDOWN(start, PTSIZE);
c0105bad:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105bb0:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0105bb3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105bb6:	25 00 00 c0 ff       	and    $0xffc00000,%eax
c0105bbb:	89 45 0c             	mov    %eax,0xc(%ebp)
    do {
        int pde_idx = PDX(start);
c0105bbe:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105bc1:	c1 e8 16             	shr    $0x16,%eax
c0105bc4:	89 45 f0             	mov    %eax,-0x10(%ebp)
        if (pgdir[pde_idx] & PTE_P) {
c0105bc7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105bca:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0105bd1:	8b 45 08             	mov    0x8(%ebp),%eax
c0105bd4:	01 d0                	add    %edx,%eax
c0105bd6:	8b 00                	mov    (%eax),%eax
c0105bd8:	83 e0 01             	and    $0x1,%eax
c0105bdb:	85 c0                	test   %eax,%eax
c0105bdd:	74 3e                	je     c0105c1d <exit_range+0xf0>
            free_page(pde2page(pgdir[pde_idx]));
c0105bdf:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105be2:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0105be9:	8b 45 08             	mov    0x8(%ebp),%eax
c0105bec:	01 d0                	add    %edx,%eax
c0105bee:	8b 00                	mov    (%eax),%eax
c0105bf0:	89 04 24             	mov    %eax,(%esp)
c0105bf3:	e8 5f f3 ff ff       	call   c0104f57 <pde2page>
c0105bf8:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0105bff:	00 
c0105c00:	89 04 24             	mov    %eax,(%esp)
c0105c03:	e8 e6 f5 ff ff       	call   c01051ee <free_pages>
            pgdir[pde_idx] = 0;
c0105c08:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105c0b:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0105c12:	8b 45 08             	mov    0x8(%ebp),%eax
c0105c15:	01 d0                	add    %edx,%eax
c0105c17:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
        }
        start += PTSIZE;
c0105c1d:	81 45 0c 00 00 40 00 	addl   $0x400000,0xc(%ebp)
    } while (start != 0 && start < end);
c0105c24:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0105c28:	74 08                	je     c0105c32 <exit_range+0x105>
c0105c2a:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105c2d:	3b 45 10             	cmp    0x10(%ebp),%eax
c0105c30:	72 8c                	jb     c0105bbe <exit_range+0x91>
}
c0105c32:	90                   	nop
c0105c33:	89 ec                	mov    %ebp,%esp
c0105c35:	5d                   	pop    %ebp
c0105c36:	c3                   	ret    

c0105c37 <copy_range>:
 * @param share 是否共享页面。
 * 
 * @return 成功返回0，失败返回错误码。
 */
int
copy_range(pde_t *to, pde_t *from, uintptr_t start, uintptr_t end, bool share) {
c0105c37:	55                   	push   %ebp
c0105c38:	89 e5                	mov    %esp,%ebp
c0105c3a:	83 ec 48             	sub    $0x48,%esp
    //确保起始地址和结束地址都是页对齐的
    assert(start % PGSIZE == 0 && end % PGSIZE == 0);
c0105c3d:	8b 45 10             	mov    0x10(%ebp),%eax
c0105c40:	25 ff 0f 00 00       	and    $0xfff,%eax
c0105c45:	85 c0                	test   %eax,%eax
c0105c47:	75 0c                	jne    c0105c55 <copy_range+0x1e>
c0105c49:	8b 45 14             	mov    0x14(%ebp),%eax
c0105c4c:	25 ff 0f 00 00       	and    $0xfff,%eax
c0105c51:	85 c0                	test   %eax,%eax
c0105c53:	74 24                	je     c0105c79 <copy_range+0x42>
c0105c55:	c7 44 24 0c 24 cf 10 	movl   $0xc010cf24,0xc(%esp)
c0105c5c:	c0 
c0105c5d:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105c64:	c0 
c0105c65:	c7 44 24 04 57 02 00 	movl   $0x257,0x4(%esp)
c0105c6c:	00 
c0105c6d:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105c74:	e8 c2 b0 ff ff       	call   c0100d3b <__panic>
    // 确保地址范围在用户空间内
    assert(USER_ACCESS(start, end));
c0105c79:	81 7d 10 ff ff 1f 00 	cmpl   $0x1fffff,0x10(%ebp)
c0105c80:	76 11                	jbe    c0105c93 <copy_range+0x5c>
c0105c82:	8b 45 10             	mov    0x10(%ebp),%eax
c0105c85:	3b 45 14             	cmp    0x14(%ebp),%eax
c0105c88:	73 09                	jae    c0105c93 <copy_range+0x5c>
c0105c8a:	81 7d 14 00 00 00 b0 	cmpl   $0xb0000000,0x14(%ebp)
c0105c91:	76 24                	jbe    c0105cb7 <copy_range+0x80>
c0105c93:	c7 44 24 0c 4d cf 10 	movl   $0xc010cf4d,0xc(%esp)
c0105c9a:	c0 
c0105c9b:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105ca2:	c0 
c0105ca3:	c7 44 24 04 59 02 00 	movl   $0x259,0x4(%esp)
c0105caa:	00 
c0105cab:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105cb2:	e8 84 b0 ff ff       	call   c0100d3b <__panic>
    // copy content by page unit. // 按页单位复制内容
    do {
        //call get_pte to find process A's pte according to the addr start
         // 调用 get_pte 根据起始地址找到进程 A 的页表项
        pte_t *ptep = get_pte(from, start, 0), *nptep;
c0105cb7:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105cbe:	00 
c0105cbf:	8b 45 10             	mov    0x10(%ebp),%eax
c0105cc2:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105cc6:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105cc9:	89 04 24             	mov    %eax,(%esp)
c0105ccc:	e8 6b fb ff ff       	call   c010583c <get_pte>
c0105cd1:	89 45 f4             	mov    %eax,-0xc(%ebp)
        if (ptep == NULL) {
c0105cd4:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105cd8:	75 1b                	jne    c0105cf5 <copy_range+0xbe>
            // 如果页表项不存在，跳过当前页
            start = ROUNDDOWN(start + PTSIZE, PTSIZE);
c0105cda:	8b 45 10             	mov    0x10(%ebp),%eax
c0105cdd:	05 00 00 40 00       	add    $0x400000,%eax
c0105ce2:	89 45 d4             	mov    %eax,-0x2c(%ebp)
c0105ce5:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0105ce8:	25 00 00 c0 ff       	and    $0xffc00000,%eax
c0105ced:	89 45 10             	mov    %eax,0x10(%ebp)
            continue ;
c0105cf0:	e9 4c 01 00 00       	jmp    c0105e41 <copy_range+0x20a>
        }
        //call get_pte to find process B's pte according to the addr start. If pte is NULL, just alloc a PT
        // 调用 get_pte 根据起始地址找到进程 B 的页表项。如果页表项不存在，分配一个新的页表
        if (*ptep & PTE_P) {
c0105cf5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105cf8:	8b 00                	mov    (%eax),%eax
c0105cfa:	83 e0 01             	and    $0x1,%eax
c0105cfd:	85 c0                	test   %eax,%eax
c0105cff:	0f 84 35 01 00 00    	je     c0105e3a <copy_range+0x203>
            if ((nptep = get_pte(to, start, 1)) == NULL) {
c0105d05:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c0105d0c:	00 
c0105d0d:	8b 45 10             	mov    0x10(%ebp),%eax
c0105d10:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105d14:	8b 45 08             	mov    0x8(%ebp),%eax
c0105d17:	89 04 24             	mov    %eax,(%esp)
c0105d1a:	e8 1d fb ff ff       	call   c010583c <get_pte>
c0105d1f:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0105d22:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0105d26:	75 0a                	jne    c0105d32 <copy_range+0xfb>
                // 分配页表失败，返回内存不足错误
                return -E_NO_MEM;
c0105d28:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
c0105d2d:	e9 26 01 00 00       	jmp    c0105e58 <copy_range+0x221>
            }
         // 获取页表项的权限
        uint32_t perm = (*ptep & PTE_USER);
c0105d32:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105d35:	8b 00                	mov    (%eax),%eax
c0105d37:	83 e0 07             	and    $0x7,%eax
c0105d3a:	89 45 ec             	mov    %eax,-0x14(%ebp)
        //get page from ptep
        // 从页表项获取物理页面
        struct Page *page = pte2page(*ptep);
c0105d3d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105d40:	8b 00                	mov    (%eax),%eax
c0105d42:	89 04 24             	mov    %eax,(%esp)
c0105d45:	e8 cd f1 ff ff       	call   c0104f17 <pte2page>
c0105d4a:	89 45 e8             	mov    %eax,-0x18(%ebp)
        // alloc a page for process B
        // 为进程 B 分配一个物理页面
        struct Page *npage=alloc_page();
c0105d4d:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0105d54:	e8 28 f4 ff ff       	call   c0105181 <alloc_pages>
c0105d59:	89 45 e4             	mov    %eax,-0x1c(%ebp)
          // 断言页面不为空
        assert(page!=NULL);
c0105d5c:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0105d60:	75 24                	jne    c0105d86 <copy_range+0x14f>
c0105d62:	c7 44 24 0c 65 cf 10 	movl   $0xc010cf65,0xc(%esp)
c0105d69:	c0 
c0105d6a:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105d71:	c0 
c0105d72:	c7 44 24 04 74 02 00 	movl   $0x274,0x4(%esp)
c0105d79:	00 
c0105d7a:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105d81:	e8 b5 af ff ff       	call   c0100d3b <__panic>
        assert(npage!=NULL);
c0105d86:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0105d8a:	75 24                	jne    c0105db0 <copy_range+0x179>
c0105d8c:	c7 44 24 0c 70 cf 10 	movl   $0xc010cf70,0xc(%esp)
c0105d93:	c0 
c0105d94:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105d9b:	c0 
c0105d9c:	c7 44 24 04 75 02 00 	movl   $0x275,0x4(%esp)
c0105da3:	00 
c0105da4:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105dab:	e8 8b af ff ff       	call   c0100d3b <__panic>
        int ret=0;
c0105db0:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
        * (2) 找到 dst_kvaddr: npage 的内核虚拟地址
        * (3) 从 src_kvaddr 复制内存到 dst_kvaddr，大小为 PGSIZE
        * (4) 建立 npage 的物理地址与线性地址 start 的映射
        */
        // 获取源页面的内核虚拟地址
        void * kva_src = page2kva(page);
c0105db7:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105dba:	89 04 24             	mov    %eax,(%esp)
c0105dbd:	e8 ff f0 ff ff       	call   c0104ec1 <page2kva>
c0105dc2:	89 45 dc             	mov    %eax,-0x24(%ebp)
        // 获取目标页面的内核虚拟地址
        void * kva_dst = page2kva(npage);
c0105dc5:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0105dc8:	89 04 24             	mov    %eax,(%esp)
c0105dcb:	e8 f1 f0 ff ff       	call   c0104ec1 <page2kva>
c0105dd0:	89 45 d8             	mov    %eax,-0x28(%ebp)
        // 将源页面的内容复制到目标页面
        memcpy(kva_dst, kva_src, PGSIZE);
c0105dd3:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0105dda:	00 
c0105ddb:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0105dde:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105de2:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0105de5:	89 04 24             	mov    %eax,(%esp)
c0105de8:	e8 e9 60 00 00       	call   c010bed6 <memcpy>
        // 将目标页面插入到目标进程的页表中，映射到线性地址 start，并设置权限 perm
        ret = page_insert(to, npage, start, perm);
c0105ded:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0105df0:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105df4:	8b 45 10             	mov    0x10(%ebp),%eax
c0105df7:	89 44 24 08          	mov    %eax,0x8(%esp)
c0105dfb:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0105dfe:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105e02:	8b 45 08             	mov    0x8(%ebp),%eax
c0105e05:	89 04 24             	mov    %eax,(%esp)
c0105e08:	e8 96 00 00 00       	call   c0105ea3 <page_insert>
c0105e0d:	89 45 e0             	mov    %eax,-0x20(%ebp)
        assert(ret == 0);
c0105e10:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c0105e14:	74 24                	je     c0105e3a <copy_range+0x203>
c0105e16:	c7 44 24 0c 7c cf 10 	movl   $0xc010cf7c,0xc(%esp)
c0105e1d:	c0 
c0105e1e:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0105e25:	c0 
c0105e26:	c7 44 24 04 9b 02 00 	movl   $0x29b,0x4(%esp)
c0105e2d:	00 
c0105e2e:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105e35:	e8 01 af ff ff       	call   c0100d3b <__panic>
        }
        start += PGSIZE;
c0105e3a:	81 45 10 00 10 00 00 	addl   $0x1000,0x10(%ebp)
    } while (start != 0 && start < end);
c0105e41:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0105e45:	74 0c                	je     c0105e53 <copy_range+0x21c>
c0105e47:	8b 45 10             	mov    0x10(%ebp),%eax
c0105e4a:	3b 45 14             	cmp    0x14(%ebp),%eax
c0105e4d:	0f 82 64 fe ff ff    	jb     c0105cb7 <copy_range+0x80>
    return 0;
c0105e53:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0105e58:	89 ec                	mov    %ebp,%esp
c0105e5a:	5d                   	pop    %ebp
c0105e5b:	c3                   	ret    

c0105e5c <page_remove>:

//page_remove - free an Page which is related linear address la and has an validated pte
//移除一个虚拟地址对应的页面
void
page_remove(pde_t *pgdir, uintptr_t la) {
c0105e5c:	55                   	push   %ebp
c0105e5d:	89 e5                	mov    %esp,%ebp
c0105e5f:	83 ec 28             	sub    $0x28,%esp
    //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。
    pte_t *ptep = get_pte(pgdir, la, 0);
c0105e62:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105e69:	00 
c0105e6a:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105e6d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105e71:	8b 45 08             	mov    0x8(%ebp),%eax
c0105e74:	89 04 24             	mov    %eax,(%esp)
c0105e77:	e8 c0 f9 ff ff       	call   c010583c <get_pte>
c0105e7c:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //如果 ptep 不为 NULL，则调用 page_remove_pte 函数移除该页表项。
    if (ptep != NULL) {
c0105e7f:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105e83:	74 19                	je     c0105e9e <page_remove+0x42>
        page_remove_pte(pgdir, la, ptep);
c0105e85:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105e88:	89 44 24 08          	mov    %eax,0x8(%esp)
c0105e8c:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105e8f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105e93:	8b 45 08             	mov    0x8(%ebp),%eax
c0105e96:	89 04 24             	mov    %eax,(%esp)
c0105e99:	e8 34 fb ff ff       	call   c01059d2 <page_remove_pte>
    }
}
c0105e9e:	90                   	nop
c0105e9f:	89 ec                	mov    %ebp,%esp
c0105ea1:	5d                   	pop    %ebp
c0105ea2:	c3                   	ret    

c0105ea3 <page_insert>:
//  perm:  the permission of this Page which is setted in related pte
// return value: always 0
//note: PT is changed, so the TLB need to be invalidate 
//将一个页面插入到页表中。
int
page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) {
c0105ea3:	55                   	push   %ebp
c0105ea4:	89 e5                	mov    %esp,%ebp
c0105ea6:	83 ec 28             	sub    $0x28,%esp
    //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。
    pte_t *ptep = get_pte(pgdir, la, 1);
c0105ea9:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c0105eb0:	00 
c0105eb1:	8b 45 10             	mov    0x10(%ebp),%eax
c0105eb4:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105eb8:	8b 45 08             	mov    0x8(%ebp),%eax
c0105ebb:	89 04 24             	mov    %eax,(%esp)
c0105ebe:	e8 79 f9 ff ff       	call   c010583c <get_pte>
c0105ec3:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //如果 ptep 为 NULL，表示内存分配失败，返回 -E_NO_MEM。
    if (ptep == NULL) {
c0105ec6:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105eca:	75 0a                	jne    c0105ed6 <page_insert+0x33>
        return -E_NO_MEM;
c0105ecc:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
c0105ed1:	e9 84 00 00 00       	jmp    c0105f5a <page_insert+0xb7>
    }
    //调用 page_ref_inc 增加页面的引用计数。
    page_ref_inc(page);
c0105ed6:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105ed9:	89 04 24             	mov    %eax,(%esp)
c0105edc:	e8 a8 f0 ff ff       	call   c0104f89 <page_ref_inc>
    //如果页表项已存在且指向当前页面，则减少页面引用计数。
    if (*ptep & PTE_P) {
c0105ee1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105ee4:	8b 00                	mov    (%eax),%eax
c0105ee6:	83 e0 01             	and    $0x1,%eax
c0105ee9:	85 c0                	test   %eax,%eax
c0105eeb:	74 3e                	je     c0105f2b <page_insert+0x88>
        struct Page *p = pte2page(*ptep);
c0105eed:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105ef0:	8b 00                	mov    (%eax),%eax
c0105ef2:	89 04 24             	mov    %eax,(%esp)
c0105ef5:	e8 1d f0 ff ff       	call   c0104f17 <pte2page>
c0105efa:	89 45 f0             	mov    %eax,-0x10(%ebp)
        if (p == page) {
c0105efd:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105f00:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0105f03:	75 0d                	jne    c0105f12 <page_insert+0x6f>
            page_ref_dec(page);
c0105f05:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105f08:	89 04 24             	mov    %eax,(%esp)
c0105f0b:	e8 90 f0 ff ff       	call   c0104fa0 <page_ref_dec>
c0105f10:	eb 19                	jmp    c0105f2b <page_insert+0x88>
        }
        //如果页表项已存在但指向其他页面，则调用 page_remove_pte 移除旧的页表项。
        else {
            page_remove_pte(pgdir, la, ptep);
c0105f12:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105f15:	89 44 24 08          	mov    %eax,0x8(%esp)
c0105f19:	8b 45 10             	mov    0x10(%ebp),%eax
c0105f1c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105f20:	8b 45 08             	mov    0x8(%ebp),%eax
c0105f23:	89 04 24             	mov    %eax,(%esp)
c0105f26:	e8 a7 fa ff ff       	call   c01059d2 <page_remove_pte>
        }
    }
    *ptep = page2pa(page) | PTE_P | perm;
c0105f2b:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105f2e:	89 04 24             	mov    %eax,(%esp)
c0105f31:	e8 2b ef ff ff       	call   c0104e61 <page2pa>
c0105f36:	0b 45 14             	or     0x14(%ebp),%eax
c0105f39:	83 c8 01             	or     $0x1,%eax
c0105f3c:	89 c2                	mov    %eax,%edx
c0105f3e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105f41:	89 10                	mov    %edx,(%eax)
    tlb_invalidate(pgdir, la);//刷新 TLB
c0105f43:	8b 45 10             	mov    0x10(%ebp),%eax
c0105f46:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105f4a:	8b 45 08             	mov    0x8(%ebp),%eax
c0105f4d:	89 04 24             	mov    %eax,(%esp)
c0105f50:	e8 09 00 00 00       	call   c0105f5e <tlb_invalidate>
    return 0;
c0105f55:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0105f5a:	89 ec                	mov    %ebp,%esp
c0105f5c:	5d                   	pop    %ebp
c0105f5d:	c3                   	ret    

c0105f5e <tlb_invalidate>:

// invalidate a TLB entry, but only if the page tables being
// edited are the ones currently in use by the processor.
//无效化指定地址的TLB条目
void
tlb_invalidate(pde_t *pgdir, uintptr_t la) {
c0105f5e:	55                   	push   %ebp
c0105f5f:	89 e5                	mov    %esp,%ebp
c0105f61:	83 ec 28             	sub    $0x28,%esp
}

static inline uintptr_t
rcr3(void) {
    uintptr_t cr3;
    asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory");
c0105f64:	0f 20 d8             	mov    %cr3,%eax
c0105f67:	89 45 f0             	mov    %eax,-0x10(%ebp)
    return cr3;
c0105f6a:	8b 55 f0             	mov    -0x10(%ebp),%edx
    //检查当前页目录地址是否与传入的页目录地址相同。
    if (rcr3() == PADDR(pgdir)) {
c0105f6d:	8b 45 08             	mov    0x8(%ebp),%eax
c0105f70:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0105f73:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c0105f7a:	77 23                	ja     c0105f9f <tlb_invalidate+0x41>
c0105f7c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105f7f:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105f83:	c7 44 24 08 a0 ce 10 	movl   $0xc010cea0,0x8(%esp)
c0105f8a:	c0 
c0105f8b:	c7 44 24 04 d7 02 00 	movl   $0x2d7,0x4(%esp)
c0105f92:	00 
c0105f93:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0105f9a:	e8 9c ad ff ff       	call   c0100d3b <__panic>
c0105f9f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105fa2:	05 00 00 00 40       	add    $0x40000000,%eax
c0105fa7:	39 d0                	cmp    %edx,%eax
c0105fa9:	75 0d                	jne    c0105fb8 <tlb_invalidate+0x5a>
        //如果相同，则调用 invlpg 函数无效化指定线性地址的TLB条目。
        invlpg((void *)la);
c0105fab:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105fae:	89 45 ec             	mov    %eax,-0x14(%ebp)
}

static inline void
invlpg(void *addr) {
    asm volatile ("invlpg (%0)" :: "r" (addr) : "memory");
c0105fb1:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0105fb4:	0f 01 38             	invlpg (%eax)
}
c0105fb7:	90                   	nop
    }
}
c0105fb8:	90                   	nop
c0105fb9:	89 ec                	mov    %ebp,%esp
c0105fbb:	5d                   	pop    %ebp
c0105fbc:	c3                   	ret    

c0105fbd <pgdir_alloc_page>:

// pgdir_alloc_page - call alloc_page & page_insert functions to 
//                  - allocate a page size memory & setup an addr map
//                  - pa<->la with linear address la and the PDT pgdir
struct Page *
pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm) {
c0105fbd:	55                   	push   %ebp
c0105fbe:	89 e5                	mov    %esp,%ebp
c0105fc0:	83 ec 28             	sub    $0x28,%esp
    struct Page *page = alloc_page();//分配一个新的页面存储在 page 指针中
c0105fc3:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0105fca:	e8 b2 f1 ff ff       	call   c0105181 <alloc_pages>
c0105fcf:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (page != NULL) {//检查 page 是否不为 NULL，即分配是否成功。
c0105fd2:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105fd6:	0f 84 b0 00 00 00    	je     c010608c <pgdir_alloc_page+0xcf>
        if (page_insert(pgdir, page, la, perm) != 0) {//将页面插入到指定的线性地址 la 处。
c0105fdc:	8b 45 10             	mov    0x10(%ebp),%eax
c0105fdf:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105fe3:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105fe6:	89 44 24 08          	mov    %eax,0x8(%esp)
c0105fea:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105fed:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105ff1:	8b 45 08             	mov    0x8(%ebp),%eax
c0105ff4:	89 04 24             	mov    %eax,(%esp)
c0105ff7:	e8 a7 fe ff ff       	call   c0105ea3 <page_insert>
c0105ffc:	85 c0                	test   %eax,%eax
c0105ffe:	74 1a                	je     c010601a <pgdir_alloc_page+0x5d>
            free_page(page);//释放分配的页面。
c0106000:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0106007:	00 
c0106008:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010600b:	89 04 24             	mov    %eax,(%esp)
c010600e:	e8 db f1 ff ff       	call   c01051ee <free_pages>
            return NULL;//返回 NULL，表示页面插入失败。
c0106013:	b8 00 00 00 00       	mov    $0x0,%eax
c0106018:	eb 75                	jmp    c010608f <pgdir_alloc_page+0xd2>
        }
        if (swap_init_ok){//检查交换区是否已初始化成功
c010601a:	a1 44 40 1a c0       	mov    0xc01a4044,%eax
c010601f:	85 c0                	test   %eax,%eax
c0106021:	74 69                	je     c010608c <pgdir_alloc_page+0xcf>
            if(check_mm_struct!=NULL) {
c0106023:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c0106028:	85 c0                	test   %eax,%eax
c010602a:	74 60                	je     c010608c <pgdir_alloc_page+0xcf>
                //将页面映射到交换区
                swap_map_swappable(check_mm_struct, la, page, 0);
c010602c:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c0106031:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0106038:	00 
c0106039:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010603c:	89 54 24 08          	mov    %edx,0x8(%esp)
c0106040:	8b 55 0c             	mov    0xc(%ebp),%edx
c0106043:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106047:	89 04 24             	mov    %eax,(%esp)
c010604a:	e8 7e 0e 00 00       	call   c0106ecd <swap_map_swappable>
                //设置页面的虚拟地址 pra_vaddr 为 la
                page->pra_vaddr=la;
c010604f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106052:	8b 55 0c             	mov    0xc(%ebp),%edx
c0106055:	89 50 1c             	mov    %edx,0x1c(%eax)
                //断言页面的引用计数为1，确保页面没有被其他地方引用。
                assert(page_ref(page) == 1);
c0106058:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010605b:	89 04 24             	mov    %eax,(%esp)
c010605e:	e8 0e ef ff ff       	call   c0104f71 <page_ref>
c0106063:	83 f8 01             	cmp    $0x1,%eax
c0106066:	74 24                	je     c010608c <pgdir_alloc_page+0xcf>
c0106068:	c7 44 24 0c 85 cf 10 	movl   $0xc010cf85,0xc(%esp)
c010606f:	c0 
c0106070:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106077:	c0 
c0106078:	c7 44 24 04 ef 02 00 	movl   $0x2ef,0x4(%esp)
c010607f:	00 
c0106080:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106087:	e8 af ac ff ff       	call   c0100d3b <__panic>
            }
        }

    }

    return page;
c010608c:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010608f:	89 ec                	mov    %ebp,%esp
c0106091:	5d                   	pop    %ebp
c0106092:	c3                   	ret    

c0106093 <check_alloc_page>:

static void
check_alloc_page(void) {
c0106093:	55                   	push   %ebp
c0106094:	89 e5                	mov    %esp,%ebp
c0106096:	83 ec 18             	sub    $0x18,%esp
    //调用内存管理器的 check 方法，用于检查内存分配是否正常。
    pmm_manager->check();
c0106099:	a1 ac 3f 1a c0       	mov    0xc01a3fac,%eax
c010609e:	8b 40 18             	mov    0x18(%eax),%eax
c01060a1:	ff d0                	call   *%eax
    cprintf("check_alloc_page() succeeded!\n");
c01060a3:	c7 04 24 9c cf 10 c0 	movl   $0xc010cf9c,(%esp)
c01060aa:	e8 c9 a2 ff ff       	call   c0100378 <cprintf>
}
c01060af:	90                   	nop
c01060b0:	89 ec                	mov    %ebp,%esp
c01060b2:	5d                   	pop    %ebp
c01060b3:	c3                   	ret    

c01060b4 <check_pgdir>:

//用于验证页目录和页表的正确性。
static void
check_pgdir(void) {
c01060b4:	55                   	push   %ebp
c01060b5:	89 e5                	mov    %esp,%ebp
c01060b7:	83 ec 38             	sub    $0x38,%esp
    //确保内存页面数量在合理范围内
    assert(npage <= KMEMSIZE / PGSIZE);
c01060ba:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c01060bf:	3d 00 80 03 00       	cmp    $0x38000,%eax
c01060c4:	76 24                	jbe    c01060ea <check_pgdir+0x36>
c01060c6:	c7 44 24 0c bb cf 10 	movl   $0xc010cfbb,0xc(%esp)
c01060cd:	c0 
c01060ce:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01060d5:	c0 
c01060d6:	c7 44 24 04 0a 03 00 	movl   $0x30a,0x4(%esp)
c01060dd:	00 
c01060de:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01060e5:	e8 51 ac ff ff       	call   c0100d3b <__panic>
    //确保页目录不为空且对齐，
    assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0);
c01060ea:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01060ef:	85 c0                	test   %eax,%eax
c01060f1:	74 0e                	je     c0106101 <check_pgdir+0x4d>
c01060f3:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01060f8:	25 ff 0f 00 00       	and    $0xfff,%eax
c01060fd:	85 c0                	test   %eax,%eax
c01060ff:	74 24                	je     c0106125 <check_pgdir+0x71>
c0106101:	c7 44 24 0c d8 cf 10 	movl   $0xc010cfd8,0xc(%esp)
c0106108:	c0 
c0106109:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106110:	c0 
c0106111:	c7 44 24 04 0c 03 00 	movl   $0x30c,0x4(%esp)
c0106118:	00 
c0106119:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106120:	e8 16 ac ff ff       	call   c0100d3b <__panic>
    //确保虚拟地址 0x0 没有映射任何页面
    assert(get_page(boot_pgdir, 0x0, NULL) == NULL);
c0106125:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c010612a:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0106131:	00 
c0106132:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0106139:	00 
c010613a:	89 04 24             	mov    %eax,(%esp)
c010613d:	e8 35 f8 ff ff       	call   c0105977 <get_page>
c0106142:	85 c0                	test   %eax,%eax
c0106144:	74 24                	je     c010616a <check_pgdir+0xb6>
c0106146:	c7 44 24 0c 10 d0 10 	movl   $0xc010d010,0xc(%esp)
c010614d:	c0 
c010614e:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106155:	c0 
c0106156:	c7 44 24 04 0e 03 00 	movl   $0x30e,0x4(%esp)
c010615d:	00 
c010615e:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106165:	e8 d1 ab ff ff       	call   c0100d3b <__panic>
    
    //定义两个页面指针 p1 和 p2
    struct Page *p1, *p2;
    //分配一个页面 p1
    p1 = alloc_page();
c010616a:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0106171:	e8 0b f0 ff ff       	call   c0105181 <alloc_pages>
c0106176:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //将 p1 插入到虚拟地址 0x0
    assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0);
c0106179:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c010617e:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0106185:	00 
c0106186:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c010618d:	00 
c010618e:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0106191:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106195:	89 04 24             	mov    %eax,(%esp)
c0106198:	e8 06 fd ff ff       	call   c0105ea3 <page_insert>
c010619d:	85 c0                	test   %eax,%eax
c010619f:	74 24                	je     c01061c5 <check_pgdir+0x111>
c01061a1:	c7 44 24 0c 38 d0 10 	movl   $0xc010d038,0xc(%esp)
c01061a8:	c0 
c01061a9:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01061b0:	c0 
c01061b1:	c7 44 24 04 15 03 00 	movl   $0x315,0x4(%esp)
c01061b8:	00 
c01061b9:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01061c0:	e8 76 ab ff ff       	call   c0100d3b <__panic>

    // 获取虚拟地址 0x0 对应的页表项指针
    pte_t *ptep;
    assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL);
c01061c5:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01061ca:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01061d1:	00 
c01061d2:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01061d9:	00 
c01061da:	89 04 24             	mov    %eax,(%esp)
c01061dd:	e8 5a f6 ff ff       	call   c010583c <get_pte>
c01061e2:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01061e5:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01061e9:	75 24                	jne    c010620f <check_pgdir+0x15b>
c01061eb:	c7 44 24 0c 64 d0 10 	movl   $0xc010d064,0xc(%esp)
c01061f2:	c0 
c01061f3:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01061fa:	c0 
c01061fb:	c7 44 24 04 19 03 00 	movl   $0x319,0x4(%esp)
c0106202:	00 
c0106203:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c010620a:	e8 2c ab ff ff       	call   c0100d3b <__panic>
    // 验证页表项对应的页面是 p1
    assert(pte2page(*ptep) == p1);
c010620f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106212:	8b 00                	mov    (%eax),%eax
c0106214:	89 04 24             	mov    %eax,(%esp)
c0106217:	e8 fb ec ff ff       	call   c0104f17 <pte2page>
c010621c:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010621f:	74 24                	je     c0106245 <check_pgdir+0x191>
c0106221:	c7 44 24 0c 91 d0 10 	movl   $0xc010d091,0xc(%esp)
c0106228:	c0 
c0106229:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106230:	c0 
c0106231:	c7 44 24 04 1b 03 00 	movl   $0x31b,0x4(%esp)
c0106238:	00 
c0106239:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106240:	e8 f6 aa ff ff       	call   c0100d3b <__panic>
    // 验证 p1 的引用计数为 1
    assert(page_ref(p1) == 1);
c0106245:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106248:	89 04 24             	mov    %eax,(%esp)
c010624b:	e8 21 ed ff ff       	call   c0104f71 <page_ref>
c0106250:	83 f8 01             	cmp    $0x1,%eax
c0106253:	74 24                	je     c0106279 <check_pgdir+0x1c5>
c0106255:	c7 44 24 0c a7 d0 10 	movl   $0xc010d0a7,0xc(%esp)
c010625c:	c0 
c010625d:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106264:	c0 
c0106265:	c7 44 24 04 1d 03 00 	movl   $0x31d,0x4(%esp)
c010626c:	00 
c010626d:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106274:	e8 c2 aa ff ff       	call   c0100d3b <__panic>
    // 获取虚拟地址 PGSIZE 对应的页表项指针
    ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1];
c0106279:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c010627e:	8b 00                	mov    (%eax),%eax
c0106280:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0106285:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0106288:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010628b:	c1 e8 0c             	shr    $0xc,%eax
c010628e:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0106291:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0106296:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c0106299:	72 23                	jb     c01062be <check_pgdir+0x20a>
c010629b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010629e:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01062a2:	c7 44 24 08 fc cd 10 	movl   $0xc010cdfc,0x8(%esp)
c01062a9:	c0 
c01062aa:	c7 44 24 04 1f 03 00 	movl   $0x31f,0x4(%esp)
c01062b1:	00 
c01062b2:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01062b9:	e8 7d aa ff ff       	call   c0100d3b <__panic>
c01062be:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01062c1:	2d 00 00 00 40       	sub    $0x40000000,%eax
c01062c6:	83 c0 04             	add    $0x4,%eax
c01062c9:	89 45 f0             	mov    %eax,-0x10(%ebp)
    assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep);
c01062cc:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01062d1:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01062d8:	00 
c01062d9:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c01062e0:	00 
c01062e1:	89 04 24             	mov    %eax,(%esp)
c01062e4:	e8 53 f5 ff ff       	call   c010583c <get_pte>
c01062e9:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01062ec:	74 24                	je     c0106312 <check_pgdir+0x25e>
c01062ee:	c7 44 24 0c bc d0 10 	movl   $0xc010d0bc,0xc(%esp)
c01062f5:	c0 
c01062f6:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01062fd:	c0 
c01062fe:	c7 44 24 04 20 03 00 	movl   $0x320,0x4(%esp)
c0106305:	00 
c0106306:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c010630d:	e8 29 aa ff ff       	call   c0100d3b <__panic>
    // 分配一个页面 p2
    p2 = alloc_page();
c0106312:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0106319:	e8 63 ee ff ff       	call   c0105181 <alloc_pages>
c010631e:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    // 将 p2 插入到虚拟地址 PGSIZE，并设置用户和写权限
    assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0);
c0106321:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106326:	c7 44 24 0c 06 00 00 	movl   $0x6,0xc(%esp)
c010632d:	00 
c010632e:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0106335:	00 
c0106336:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0106339:	89 54 24 04          	mov    %edx,0x4(%esp)
c010633d:	89 04 24             	mov    %eax,(%esp)
c0106340:	e8 5e fb ff ff       	call   c0105ea3 <page_insert>
c0106345:	85 c0                	test   %eax,%eax
c0106347:	74 24                	je     c010636d <check_pgdir+0x2b9>
c0106349:	c7 44 24 0c e4 d0 10 	movl   $0xc010d0e4,0xc(%esp)
c0106350:	c0 
c0106351:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106358:	c0 
c0106359:	c7 44 24 04 24 03 00 	movl   $0x324,0x4(%esp)
c0106360:	00 
c0106361:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106368:	e8 ce a9 ff ff       	call   c0100d3b <__panic>
    // 获取虚拟地址 PGSIZE 对应的页表项指针
    assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL);
c010636d:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106372:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0106379:	00 
c010637a:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0106381:	00 
c0106382:	89 04 24             	mov    %eax,(%esp)
c0106385:	e8 b2 f4 ff ff       	call   c010583c <get_pte>
c010638a:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010638d:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0106391:	75 24                	jne    c01063b7 <check_pgdir+0x303>
c0106393:	c7 44 24 0c 1c d1 10 	movl   $0xc010d11c,0xc(%esp)
c010639a:	c0 
c010639b:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01063a2:	c0 
c01063a3:	c7 44 24 04 26 03 00 	movl   $0x326,0x4(%esp)
c01063aa:	00 
c01063ab:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01063b2:	e8 84 a9 ff ff       	call   c0100d3b <__panic>
    // 验证页表项设置了用户权限
    assert(*ptep & PTE_U);
c01063b7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01063ba:	8b 00                	mov    (%eax),%eax
c01063bc:	83 e0 04             	and    $0x4,%eax
c01063bf:	85 c0                	test   %eax,%eax
c01063c1:	75 24                	jne    c01063e7 <check_pgdir+0x333>
c01063c3:	c7 44 24 0c 4c d1 10 	movl   $0xc010d14c,0xc(%esp)
c01063ca:	c0 
c01063cb:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01063d2:	c0 
c01063d3:	c7 44 24 04 28 03 00 	movl   $0x328,0x4(%esp)
c01063da:	00 
c01063db:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01063e2:	e8 54 a9 ff ff       	call   c0100d3b <__panic>
    // 验证页表项设置了写权限
    assert(*ptep & PTE_W);
c01063e7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01063ea:	8b 00                	mov    (%eax),%eax
c01063ec:	83 e0 02             	and    $0x2,%eax
c01063ef:	85 c0                	test   %eax,%eax
c01063f1:	75 24                	jne    c0106417 <check_pgdir+0x363>
c01063f3:	c7 44 24 0c 5a d1 10 	movl   $0xc010d15a,0xc(%esp)
c01063fa:	c0 
c01063fb:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106402:	c0 
c0106403:	c7 44 24 04 2a 03 00 	movl   $0x32a,0x4(%esp)
c010640a:	00 
c010640b:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106412:	e8 24 a9 ff ff       	call   c0100d3b <__panic>
    // 验证页目录项设置了用户权限
    assert(boot_pgdir[0] & PTE_U);
c0106417:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c010641c:	8b 00                	mov    (%eax),%eax
c010641e:	83 e0 04             	and    $0x4,%eax
c0106421:	85 c0                	test   %eax,%eax
c0106423:	75 24                	jne    c0106449 <check_pgdir+0x395>
c0106425:	c7 44 24 0c 68 d1 10 	movl   $0xc010d168,0xc(%esp)
c010642c:	c0 
c010642d:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106434:	c0 
c0106435:	c7 44 24 04 2c 03 00 	movl   $0x32c,0x4(%esp)
c010643c:	00 
c010643d:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106444:	e8 f2 a8 ff ff       	call   c0100d3b <__panic>
    // 验证 p2 的引用计数为 1
    assert(page_ref(p2) == 1);
c0106449:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010644c:	89 04 24             	mov    %eax,(%esp)
c010644f:	e8 1d eb ff ff       	call   c0104f71 <page_ref>
c0106454:	83 f8 01             	cmp    $0x1,%eax
c0106457:	74 24                	je     c010647d <check_pgdir+0x3c9>
c0106459:	c7 44 24 0c 7e d1 10 	movl   $0xc010d17e,0xc(%esp)
c0106460:	c0 
c0106461:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106468:	c0 
c0106469:	c7 44 24 04 2e 03 00 	movl   $0x32e,0x4(%esp)
c0106470:	00 
c0106471:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106478:	e8 be a8 ff ff       	call   c0100d3b <__panic>

    // 将 p1 插入到虚拟地址 PGSIZE，替换掉 p2
    assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0);
c010647d:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106482:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0106489:	00 
c010648a:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0106491:	00 
c0106492:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0106495:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106499:	89 04 24             	mov    %eax,(%esp)
c010649c:	e8 02 fa ff ff       	call   c0105ea3 <page_insert>
c01064a1:	85 c0                	test   %eax,%eax
c01064a3:	74 24                	je     c01064c9 <check_pgdir+0x415>
c01064a5:	c7 44 24 0c 90 d1 10 	movl   $0xc010d190,0xc(%esp)
c01064ac:	c0 
c01064ad:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01064b4:	c0 
c01064b5:	c7 44 24 04 31 03 00 	movl   $0x331,0x4(%esp)
c01064bc:	00 
c01064bd:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01064c4:	e8 72 a8 ff ff       	call   c0100d3b <__panic>
    // 验证 p1 的引用计数增加到 2
    assert(page_ref(p1) == 2);
c01064c9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01064cc:	89 04 24             	mov    %eax,(%esp)
c01064cf:	e8 9d ea ff ff       	call   c0104f71 <page_ref>
c01064d4:	83 f8 02             	cmp    $0x2,%eax
c01064d7:	74 24                	je     c01064fd <check_pgdir+0x449>
c01064d9:	c7 44 24 0c bc d1 10 	movl   $0xc010d1bc,0xc(%esp)
c01064e0:	c0 
c01064e1:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01064e8:	c0 
c01064e9:	c7 44 24 04 33 03 00 	movl   $0x333,0x4(%esp)
c01064f0:	00 
c01064f1:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01064f8:	e8 3e a8 ff ff       	call   c0100d3b <__panic>
    // 验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c01064fd:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106500:	89 04 24             	mov    %eax,(%esp)
c0106503:	e8 69 ea ff ff       	call   c0104f71 <page_ref>
c0106508:	85 c0                	test   %eax,%eax
c010650a:	74 24                	je     c0106530 <check_pgdir+0x47c>
c010650c:	c7 44 24 0c ce d1 10 	movl   $0xc010d1ce,0xc(%esp)
c0106513:	c0 
c0106514:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c010651b:	c0 
c010651c:	c7 44 24 04 35 03 00 	movl   $0x335,0x4(%esp)
c0106523:	00 
c0106524:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c010652b:	e8 0b a8 ff ff       	call   c0100d3b <__panic>
     // 获取虚拟地址 PGSIZE 对应的页表项指针
    assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL);
c0106530:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106535:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c010653c:	00 
c010653d:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0106544:	00 
c0106545:	89 04 24             	mov    %eax,(%esp)
c0106548:	e8 ef f2 ff ff       	call   c010583c <get_pte>
c010654d:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0106550:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0106554:	75 24                	jne    c010657a <check_pgdir+0x4c6>
c0106556:	c7 44 24 0c 1c d1 10 	movl   $0xc010d11c,0xc(%esp)
c010655d:	c0 
c010655e:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106565:	c0 
c0106566:	c7 44 24 04 37 03 00 	movl   $0x337,0x4(%esp)
c010656d:	00 
c010656e:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106575:	e8 c1 a7 ff ff       	call   c0100d3b <__panic>
    // 验证页表项对应的页面是 p1
    assert(pte2page(*ptep) == p1);
c010657a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010657d:	8b 00                	mov    (%eax),%eax
c010657f:	89 04 24             	mov    %eax,(%esp)
c0106582:	e8 90 e9 ff ff       	call   c0104f17 <pte2page>
c0106587:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010658a:	74 24                	je     c01065b0 <check_pgdir+0x4fc>
c010658c:	c7 44 24 0c 91 d0 10 	movl   $0xc010d091,0xc(%esp)
c0106593:	c0 
c0106594:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c010659b:	c0 
c010659c:	c7 44 24 04 39 03 00 	movl   $0x339,0x4(%esp)
c01065a3:	00 
c01065a4:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01065ab:	e8 8b a7 ff ff       	call   c0100d3b <__panic>
     // 验证页表项没有设置用户权限
    assert((*ptep & PTE_U) == 0);
c01065b0:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01065b3:	8b 00                	mov    (%eax),%eax
c01065b5:	83 e0 04             	and    $0x4,%eax
c01065b8:	85 c0                	test   %eax,%eax
c01065ba:	74 24                	je     c01065e0 <check_pgdir+0x52c>
c01065bc:	c7 44 24 0c e0 d1 10 	movl   $0xc010d1e0,0xc(%esp)
c01065c3:	c0 
c01065c4:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01065cb:	c0 
c01065cc:	c7 44 24 04 3b 03 00 	movl   $0x33b,0x4(%esp)
c01065d3:	00 
c01065d4:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01065db:	e8 5b a7 ff ff       	call   c0100d3b <__panic>
    
    //移除虚拟地址 0x0 的映射，
    page_remove(boot_pgdir, 0x0);
c01065e0:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01065e5:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01065ec:	00 
c01065ed:	89 04 24             	mov    %eax,(%esp)
c01065f0:	e8 67 f8 ff ff       	call   c0105e5c <page_remove>
    //验证 p1 的引用计数减少到 1。
    assert(page_ref(p1) == 1);
c01065f5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01065f8:	89 04 24             	mov    %eax,(%esp)
c01065fb:	e8 71 e9 ff ff       	call   c0104f71 <page_ref>
c0106600:	83 f8 01             	cmp    $0x1,%eax
c0106603:	74 24                	je     c0106629 <check_pgdir+0x575>
c0106605:	c7 44 24 0c a7 d0 10 	movl   $0xc010d0a7,0xc(%esp)
c010660c:	c0 
c010660d:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106614:	c0 
c0106615:	c7 44 24 04 40 03 00 	movl   $0x340,0x4(%esp)
c010661c:	00 
c010661d:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106624:	e8 12 a7 ff ff       	call   c0100d3b <__panic>
    //验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c0106629:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010662c:	89 04 24             	mov    %eax,(%esp)
c010662f:	e8 3d e9 ff ff       	call   c0104f71 <page_ref>
c0106634:	85 c0                	test   %eax,%eax
c0106636:	74 24                	je     c010665c <check_pgdir+0x5a8>
c0106638:	c7 44 24 0c ce d1 10 	movl   $0xc010d1ce,0xc(%esp)
c010663f:	c0 
c0106640:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106647:	c0 
c0106648:	c7 44 24 04 42 03 00 	movl   $0x342,0x4(%esp)
c010664f:	00 
c0106650:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106657:	e8 df a6 ff ff       	call   c0100d3b <__panic>

    //移除虚拟地址 PGSIZE 的映射，
    page_remove(boot_pgdir, PGSIZE);
c010665c:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106661:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0106668:	00 
c0106669:	89 04 24             	mov    %eax,(%esp)
c010666c:	e8 eb f7 ff ff       	call   c0105e5c <page_remove>
    //验证 p1 的引用计数减少到 0
    assert(page_ref(p1) == 0);
c0106671:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106674:	89 04 24             	mov    %eax,(%esp)
c0106677:	e8 f5 e8 ff ff       	call   c0104f71 <page_ref>
c010667c:	85 c0                	test   %eax,%eax
c010667e:	74 24                	je     c01066a4 <check_pgdir+0x5f0>
c0106680:	c7 44 24 0c f5 d1 10 	movl   $0xc010d1f5,0xc(%esp)
c0106687:	c0 
c0106688:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c010668f:	c0 
c0106690:	c7 44 24 04 47 03 00 	movl   $0x347,0x4(%esp)
c0106697:	00 
c0106698:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c010669f:	e8 97 a6 ff ff       	call   c0100d3b <__panic>
    //验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c01066a4:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01066a7:	89 04 24             	mov    %eax,(%esp)
c01066aa:	e8 c2 e8 ff ff       	call   c0104f71 <page_ref>
c01066af:	85 c0                	test   %eax,%eax
c01066b1:	74 24                	je     c01066d7 <check_pgdir+0x623>
c01066b3:	c7 44 24 0c ce d1 10 	movl   $0xc010d1ce,0xc(%esp)
c01066ba:	c0 
c01066bb:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01066c2:	c0 
c01066c3:	c7 44 24 04 49 03 00 	movl   $0x349,0x4(%esp)
c01066ca:	00 
c01066cb:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01066d2:	e8 64 a6 ff ff       	call   c0100d3b <__panic>
    
    //验证页目录的第一页表的引用计数为 1。
    assert(page_ref(pde2page(boot_pgdir[0])) == 1);
c01066d7:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01066dc:	8b 00                	mov    (%eax),%eax
c01066de:	89 04 24             	mov    %eax,(%esp)
c01066e1:	e8 71 e8 ff ff       	call   c0104f57 <pde2page>
c01066e6:	89 04 24             	mov    %eax,(%esp)
c01066e9:	e8 83 e8 ff ff       	call   c0104f71 <page_ref>
c01066ee:	83 f8 01             	cmp    $0x1,%eax
c01066f1:	74 24                	je     c0106717 <check_pgdir+0x663>
c01066f3:	c7 44 24 0c 08 d2 10 	movl   $0xc010d208,0xc(%esp)
c01066fa:	c0 
c01066fb:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106702:	c0 
c0106703:	c7 44 24 04 4c 03 00 	movl   $0x34c,0x4(%esp)
c010670a:	00 
c010670b:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106712:	e8 24 a6 ff ff       	call   c0100d3b <__panic>
    //释放页目录的第一页表
    free_page(pde2page(boot_pgdir[0]));
c0106717:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c010671c:	8b 00                	mov    (%eax),%eax
c010671e:	89 04 24             	mov    %eax,(%esp)
c0106721:	e8 31 e8 ff ff       	call   c0104f57 <pde2page>
c0106726:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010672d:	00 
c010672e:	89 04 24             	mov    %eax,(%esp)
c0106731:	e8 b8 ea ff ff       	call   c01051ee <free_pages>
    //清空页目录的第一页表
    boot_pgdir[0] = 0;
c0106736:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c010673b:	c7 00 00 00 00 00    	movl   $0x0,(%eax)

    cprintf("check_pgdir() succeeded!\n");
c0106741:	c7 04 24 2f d2 10 c0 	movl   $0xc010d22f,(%esp)
c0106748:	e8 2b 9c ff ff       	call   c0100378 <cprintf>
}
c010674d:	90                   	nop
c010674e:	89 ec                	mov    %ebp,%esp
c0106750:	5d                   	pop    %ebp
c0106751:	c3                   	ret    

c0106752 <check_boot_pgdir>:

//检查内核页表 boot_pgdir 的正确性
static void
check_boot_pgdir(void) {
c0106752:	55                   	push   %ebp
c0106753:	89 e5                	mov    %esp,%ebp
c0106755:	83 ec 38             	sub    $0x38,%esp
    pte_t *ptep;// 定义一个指向页表项的指针
    int i;
    for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面
c0106758:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c010675f:	e9 ca 00 00 00       	jmp    c010682e <check_boot_pgdir+0xdc>
        // 获取第 i 个页面的页表项，并确保其不为空
        assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL);
c0106764:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106767:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c010676a:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010676d:	c1 e8 0c             	shr    $0xc,%eax
c0106770:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0106773:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0106778:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c010677b:	72 23                	jb     c01067a0 <check_boot_pgdir+0x4e>
c010677d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106780:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0106784:	c7 44 24 08 fc cd 10 	movl   $0xc010cdfc,0x8(%esp)
c010678b:	c0 
c010678c:	c7 44 24 04 5c 03 00 	movl   $0x35c,0x4(%esp)
c0106793:	00 
c0106794:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c010679b:	e8 9b a5 ff ff       	call   c0100d3b <__panic>
c01067a0:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01067a3:	2d 00 00 00 40       	sub    $0x40000000,%eax
c01067a8:	89 c2                	mov    %eax,%edx
c01067aa:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01067af:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01067b6:	00 
c01067b7:	89 54 24 04          	mov    %edx,0x4(%esp)
c01067bb:	89 04 24             	mov    %eax,(%esp)
c01067be:	e8 79 f0 ff ff       	call   c010583c <get_pte>
c01067c3:	89 45 dc             	mov    %eax,-0x24(%ebp)
c01067c6:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c01067ca:	75 24                	jne    c01067f0 <check_boot_pgdir+0x9e>
c01067cc:	c7 44 24 0c 4c d2 10 	movl   $0xc010d24c,0xc(%esp)
c01067d3:	c0 
c01067d4:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01067db:	c0 
c01067dc:	c7 44 24 04 5c 03 00 	movl   $0x35c,0x4(%esp)
c01067e3:	00 
c01067e4:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01067eb:	e8 4b a5 ff ff       	call   c0100d3b <__panic>
        // 验证页表项的物理地址是否正确
        assert(PTE_ADDR(*ptep) == i);
c01067f0:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01067f3:	8b 00                	mov    (%eax),%eax
c01067f5:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c01067fa:	89 c2                	mov    %eax,%edx
c01067fc:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01067ff:	39 c2                	cmp    %eax,%edx
c0106801:	74 24                	je     c0106827 <check_boot_pgdir+0xd5>
c0106803:	c7 44 24 0c 89 d2 10 	movl   $0xc010d289,0xc(%esp)
c010680a:	c0 
c010680b:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106812:	c0 
c0106813:	c7 44 24 04 5e 03 00 	movl   $0x35e,0x4(%esp)
c010681a:	00 
c010681b:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106822:	e8 14 a5 ff ff       	call   c0100d3b <__panic>
    for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面
c0106827:	81 45 f4 00 10 00 00 	addl   $0x1000,-0xc(%ebp)
c010682e:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0106831:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0106836:	39 c2                	cmp    %eax,%edx
c0106838:	0f 82 26 ff ff ff    	jb     c0106764 <check_boot_pgdir+0x12>
    }
    // 验证页目录项的物理地址是否正确
    assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir));
c010683e:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106843:	05 ac 0f 00 00       	add    $0xfac,%eax
c0106848:	8b 00                	mov    (%eax),%eax
c010684a:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010684f:	89 c2                	mov    %eax,%edx
c0106851:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106856:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0106859:	81 7d f0 ff ff ff bf 	cmpl   $0xbfffffff,-0x10(%ebp)
c0106860:	77 23                	ja     c0106885 <check_boot_pgdir+0x133>
c0106862:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106865:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0106869:	c7 44 24 08 a0 ce 10 	movl   $0xc010cea0,0x8(%esp)
c0106870:	c0 
c0106871:	c7 44 24 04 61 03 00 	movl   $0x361,0x4(%esp)
c0106878:	00 
c0106879:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106880:	e8 b6 a4 ff ff       	call   c0100d3b <__panic>
c0106885:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106888:	05 00 00 00 40       	add    $0x40000000,%eax
c010688d:	39 d0                	cmp    %edx,%eax
c010688f:	74 24                	je     c01068b5 <check_boot_pgdir+0x163>
c0106891:	c7 44 24 0c a0 d2 10 	movl   $0xc010d2a0,0xc(%esp)
c0106898:	c0 
c0106899:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01068a0:	c0 
c01068a1:	c7 44 24 04 61 03 00 	movl   $0x361,0x4(%esp)
c01068a8:	00 
c01068a9:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01068b0:	e8 86 a4 ff ff       	call   c0100d3b <__panic>

    assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0
c01068b5:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01068ba:	8b 00                	mov    (%eax),%eax
c01068bc:	85 c0                	test   %eax,%eax
c01068be:	74 24                	je     c01068e4 <check_boot_pgdir+0x192>
c01068c0:	c7 44 24 0c d4 d2 10 	movl   $0xc010d2d4,0xc(%esp)
c01068c7:	c0 
c01068c8:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01068cf:	c0 
c01068d0:	c7 44 24 04 63 03 00 	movl   $0x363,0x4(%esp)
c01068d7:	00 
c01068d8:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01068df:	e8 57 a4 ff ff       	call   c0100d3b <__panic>

    struct Page *p;// 定义一个指向页面的指针
    p = alloc_page();// 分配一个页面
c01068e4:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01068eb:	e8 91 e8 ff ff       	call   c0105181 <alloc_pages>
c01068f0:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 将页面插入到虚拟地址 0x100，并确保操作成功
    assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0);
c01068f3:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c01068f8:	c7 44 24 0c 02 00 00 	movl   $0x2,0xc(%esp)
c01068ff:	00 
c0106900:	c7 44 24 08 00 01 00 	movl   $0x100,0x8(%esp)
c0106907:	00 
c0106908:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010690b:	89 54 24 04          	mov    %edx,0x4(%esp)
c010690f:	89 04 24             	mov    %eax,(%esp)
c0106912:	e8 8c f5 ff ff       	call   c0105ea3 <page_insert>
c0106917:	85 c0                	test   %eax,%eax
c0106919:	74 24                	je     c010693f <check_boot_pgdir+0x1ed>
c010691b:	c7 44 24 0c e8 d2 10 	movl   $0xc010d2e8,0xc(%esp)
c0106922:	c0 
c0106923:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c010692a:	c0 
c010692b:	c7 44 24 04 68 03 00 	movl   $0x368,0x4(%esp)
c0106932:	00 
c0106933:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c010693a:	e8 fc a3 ff ff       	call   c0100d3b <__panic>
    assert(page_ref(p) == 1);// 验证页面的引用计数为1
c010693f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106942:	89 04 24             	mov    %eax,(%esp)
c0106945:	e8 27 e6 ff ff       	call   c0104f71 <page_ref>
c010694a:	83 f8 01             	cmp    $0x1,%eax
c010694d:	74 24                	je     c0106973 <check_boot_pgdir+0x221>
c010694f:	c7 44 24 0c 16 d3 10 	movl   $0xc010d316,0xc(%esp)
c0106956:	c0 
c0106957:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c010695e:	c0 
c010695f:	c7 44 24 04 69 03 00 	movl   $0x369,0x4(%esp)
c0106966:	00 
c0106967:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c010696e:	e8 c8 a3 ff ff       	call   c0100d3b <__panic>
    // 将页面插入到虚拟地址 0x100 + PGSIZE，并确保操作成功
    assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0);
c0106973:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106978:	c7 44 24 0c 02 00 00 	movl   $0x2,0xc(%esp)
c010697f:	00 
c0106980:	c7 44 24 08 00 11 00 	movl   $0x1100,0x8(%esp)
c0106987:	00 
c0106988:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010698b:	89 54 24 04          	mov    %edx,0x4(%esp)
c010698f:	89 04 24             	mov    %eax,(%esp)
c0106992:	e8 0c f5 ff ff       	call   c0105ea3 <page_insert>
c0106997:	85 c0                	test   %eax,%eax
c0106999:	74 24                	je     c01069bf <check_boot_pgdir+0x26d>
c010699b:	c7 44 24 0c 28 d3 10 	movl   $0xc010d328,0xc(%esp)
c01069a2:	c0 
c01069a3:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01069aa:	c0 
c01069ab:	c7 44 24 04 6b 03 00 	movl   $0x36b,0x4(%esp)
c01069b2:	00 
c01069b3:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01069ba:	e8 7c a3 ff ff       	call   c0100d3b <__panic>
    assert(page_ref(p) == 2);// 验证页面的引用计数为2
c01069bf:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01069c2:	89 04 24             	mov    %eax,(%esp)
c01069c5:	e8 a7 e5 ff ff       	call   c0104f71 <page_ref>
c01069ca:	83 f8 02             	cmp    $0x2,%eax
c01069cd:	74 24                	je     c01069f3 <check_boot_pgdir+0x2a1>
c01069cf:	c7 44 24 0c 5f d3 10 	movl   $0xc010d35f,0xc(%esp)
c01069d6:	c0 
c01069d7:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c01069de:	c0 
c01069df:	c7 44 24 04 6c 03 00 	movl   $0x36c,0x4(%esp)
c01069e6:	00 
c01069e7:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c01069ee:	e8 48 a3 ff ff       	call   c0100d3b <__panic>

    const char *str = "ucore: Hello world!!";// 定义一个字符串
c01069f3:	c7 45 e8 70 d3 10 c0 	movl   $0xc010d370,-0x18(%ebp)
    strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100
c01069fa:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01069fd:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106a01:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c0106a08:	e8 14 51 00 00       	call   c010bb21 <strcpy>
    // 验证两个映射地址的数据是否一致
    assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0);
c0106a0d:	c7 44 24 04 00 11 00 	movl   $0x1100,0x4(%esp)
c0106a14:	00 
c0106a15:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c0106a1c:	e8 78 51 00 00       	call   c010bb99 <strcmp>
c0106a21:	85 c0                	test   %eax,%eax
c0106a23:	74 24                	je     c0106a49 <check_boot_pgdir+0x2f7>
c0106a25:	c7 44 24 0c 88 d3 10 	movl   $0xc010d388,0xc(%esp)
c0106a2c:	c0 
c0106a2d:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106a34:	c0 
c0106a35:	c7 44 24 04 71 03 00 	movl   $0x371,0x4(%esp)
c0106a3c:	00 
c0106a3d:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106a44:	e8 f2 a2 ff ff       	call   c0100d3b <__panic>
    // 在页面的 0x100 偏移处设置字符串结束符
    *(char *)(page2kva(p) + 0x100) = '\0';
c0106a49:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106a4c:	89 04 24             	mov    %eax,(%esp)
c0106a4f:	e8 6d e4 ff ff       	call   c0104ec1 <page2kva>
c0106a54:	05 00 01 00 00       	add    $0x100,%eax
c0106a59:	c6 00 00             	movb   $0x0,(%eax)
    assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0
c0106a5c:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c0106a63:	e8 5f 50 00 00       	call   c010bac7 <strlen>
c0106a68:	85 c0                	test   %eax,%eax
c0106a6a:	74 24                	je     c0106a90 <check_boot_pgdir+0x33e>
c0106a6c:	c7 44 24 0c c0 d3 10 	movl   $0xc010d3c0,0xc(%esp)
c0106a73:	c0 
c0106a74:	c7 44 24 08 e9 ce 10 	movl   $0xc010cee9,0x8(%esp)
c0106a7b:	c0 
c0106a7c:	c7 44 24 04 74 03 00 	movl   $0x374,0x4(%esp)
c0106a83:	00 
c0106a84:	c7 04 24 c4 ce 10 c0 	movl   $0xc010cec4,(%esp)
c0106a8b:	e8 ab a2 ff ff       	call   c0100d3b <__panic>

    free_page(p);// 释放页面 p
c0106a90:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0106a97:	00 
c0106a98:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106a9b:	89 04 24             	mov    %eax,(%esp)
c0106a9e:	e8 4b e7 ff ff       	call   c01051ee <free_pages>
    free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面
c0106aa3:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106aa8:	8b 00                	mov    (%eax),%eax
c0106aaa:	89 04 24             	mov    %eax,(%esp)
c0106aad:	e8 a5 e4 ff ff       	call   c0104f57 <pde2page>
c0106ab2:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0106ab9:	00 
c0106aba:	89 04 24             	mov    %eax,(%esp)
c0106abd:	e8 2c e7 ff ff       	call   c01051ee <free_pages>
    boot_pgdir[0] = 0;// 将页目录的第一个项设为0
c0106ac2:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106ac7:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
    
    tlb_invalidate(boot_pgdir, 0x100);
c0106acd:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106ad2:	c7 44 24 04 00 01 00 	movl   $0x100,0x4(%esp)
c0106ad9:	00 
c0106ada:	89 04 24             	mov    %eax,(%esp)
c0106add:	e8 7c f4 ff ff       	call   c0105f5e <tlb_invalidate>
    tlb_invalidate(boot_pgdir, 0x100+PGSIZE);
c0106ae2:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0106ae7:	c7 44 24 04 00 11 00 	movl   $0x1100,0x4(%esp)
c0106aee:	00 
c0106aef:	89 04 24             	mov    %eax,(%esp)
c0106af2:	e8 67 f4 ff ff       	call   c0105f5e <tlb_invalidate>
    
    cprintf("check_boot_pgdir() succeeded!\n");
c0106af7:	c7 04 24 e4 d3 10 c0 	movl   $0xc010d3e4,(%esp)
c0106afe:	e8 75 98 ff ff       	call   c0100378 <cprintf>
}
c0106b03:	90                   	nop
c0106b04:	89 ec                	mov    %ebp,%esp
c0106b06:	5d                   	pop    %ebp
c0106b07:	c3                   	ret    

c0106b08 <perm2str>:

//perm2str - use string 'u,r,w,-' to present the permission
static const char *
perm2str(int perm) {
c0106b08:	55                   	push   %ebp
c0106b09:	89 e5                	mov    %esp,%ebp
    //定义一个静态字符数组 str，长度为4
    static char str[4];
    //如果 perm 与 PTE_U 按位与的结果不为0，则 str[0] 设置为 'u'，否则设置为 '-'
    str[0] = (perm & PTE_U) ? 'u' : '-';
c0106b0b:	8b 45 08             	mov    0x8(%ebp),%eax
c0106b0e:	83 e0 04             	and    $0x4,%eax
c0106b11:	85 c0                	test   %eax,%eax
c0106b13:	74 04                	je     c0106b19 <perm2str+0x11>
c0106b15:	b0 75                	mov    $0x75,%al
c0106b17:	eb 02                	jmp    c0106b1b <perm2str+0x13>
c0106b19:	b0 2d                	mov    $0x2d,%al
c0106b1b:	a2 28 40 1a c0       	mov    %al,0xc01a4028
    //str[1] 始终设置为 'r'
    str[1] = 'r';
c0106b20:	c6 05 29 40 1a c0 72 	movb   $0x72,0xc01a4029
    //如果 perm 与 PTE_W 按位与的结果不为0，则 str[2] 设置为 'w'，否则设置为 '-'
    str[2] = (perm & PTE_W) ? 'w' : '-';
c0106b27:	8b 45 08             	mov    0x8(%ebp),%eax
c0106b2a:	83 e0 02             	and    $0x2,%eax
c0106b2d:	85 c0                	test   %eax,%eax
c0106b2f:	74 04                	je     c0106b35 <perm2str+0x2d>
c0106b31:	b0 77                	mov    $0x77,%al
c0106b33:	eb 02                	jmp    c0106b37 <perm2str+0x2f>
c0106b35:	b0 2d                	mov    $0x2d,%al
c0106b37:	a2 2a 40 1a c0       	mov    %al,0xc01a402a
    //str[3] 设置为字符串结束符 \0
    str[3] = '\0';
c0106b3c:	c6 05 2b 40 1a c0 00 	movb   $0x0,0xc01a402b
    return str;
c0106b43:	b8 28 40 1a c0       	mov    $0xc01a4028,%eax
}
c0106b48:	5d                   	pop    %ebp
c0106b49:	c3                   	ret    

c0106b4a <get_pgtable_items>:
//  left_store:  the pointer of the high side of table's next range
//  right_store: the pointer of the low side of table's next range
// return value: 0 - not a invalid item range, perm - a valid item range with perm permission 
//从页表中获取指定范围内的有效项，并根据权限进行处理。
static int
get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) {
c0106b4a:	55                   	push   %ebp
c0106b4b:	89 e5                	mov    %esp,%ebp
c0106b4d:	83 ec 10             	sub    $0x10,%esp
    if (start >= right) {// 检查起始索引是否超出右边界
c0106b50:	8b 45 10             	mov    0x10(%ebp),%eax
c0106b53:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0106b56:	72 0d                	jb     c0106b65 <get_pgtable_items+0x1b>
        return 0;// 如果超出右边界，返回0
c0106b58:	b8 00 00 00 00       	mov    $0x0,%eax
c0106b5d:	e9 98 00 00 00       	jmp    c0106bfa <get_pgtable_items+0xb0>
    }
    while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项（PTE_P位为1的项）
        start ++;// 索引递增
c0106b62:	ff 45 10             	incl   0x10(%ebp)
    while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项（PTE_P位为1的项）
c0106b65:	8b 45 10             	mov    0x10(%ebp),%eax
c0106b68:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0106b6b:	73 18                	jae    c0106b85 <get_pgtable_items+0x3b>
c0106b6d:	8b 45 10             	mov    0x10(%ebp),%eax
c0106b70:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0106b77:	8b 45 14             	mov    0x14(%ebp),%eax
c0106b7a:	01 d0                	add    %edx,%eax
c0106b7c:	8b 00                	mov    (%eax),%eax
c0106b7e:	83 e0 01             	and    $0x1,%eax
c0106b81:	85 c0                	test   %eax,%eax
c0106b83:	74 dd                	je     c0106b62 <get_pgtable_items+0x18>
    }
    if (start < right) {// 检查是否找到有效项
c0106b85:	8b 45 10             	mov    0x10(%ebp),%eax
c0106b88:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0106b8b:	73 68                	jae    c0106bf5 <get_pgtable_items+0xab>
        if (left_store != NULL) {// 如果left_store不为NULL
c0106b8d:	83 7d 18 00          	cmpl   $0x0,0x18(%ebp)
c0106b91:	74 08                	je     c0106b9b <get_pgtable_items+0x51>
            *left_store = start;// 记录左边界索引
c0106b93:	8b 45 18             	mov    0x18(%ebp),%eax
c0106b96:	8b 55 10             	mov    0x10(%ebp),%edx
c0106b99:	89 10                	mov    %edx,(%eax)
        }
        int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引
c0106b9b:	8b 45 10             	mov    0x10(%ebp),%eax
c0106b9e:	8d 50 01             	lea    0x1(%eax),%edx
c0106ba1:	89 55 10             	mov    %edx,0x10(%ebp)
c0106ba4:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0106bab:	8b 45 14             	mov    0x14(%ebp),%eax
c0106bae:	01 d0                	add    %edx,%eax
c0106bb0:	8b 00                	mov    (%eax),%eax
c0106bb2:	83 e0 07             	and    $0x7,%eax
c0106bb5:	89 45 fc             	mov    %eax,-0x4(%ebp)
        while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项
c0106bb8:	eb 03                	jmp    c0106bbd <get_pgtable_items+0x73>
            start ++;// 索引递增
c0106bba:	ff 45 10             	incl   0x10(%ebp)
        while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项
c0106bbd:	8b 45 10             	mov    0x10(%ebp),%eax
c0106bc0:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0106bc3:	73 1d                	jae    c0106be2 <get_pgtable_items+0x98>
c0106bc5:	8b 45 10             	mov    0x10(%ebp),%eax
c0106bc8:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0106bcf:	8b 45 14             	mov    0x14(%ebp),%eax
c0106bd2:	01 d0                	add    %edx,%eax
c0106bd4:	8b 00                	mov    (%eax),%eax
c0106bd6:	83 e0 07             	and    $0x7,%eax
c0106bd9:	89 c2                	mov    %eax,%edx
c0106bdb:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0106bde:	39 c2                	cmp    %eax,%edx
c0106be0:	74 d8                	je     c0106bba <get_pgtable_items+0x70>
        }
        if (right_store != NULL) {// 如果right_store不为NULL
c0106be2:	83 7d 1c 00          	cmpl   $0x0,0x1c(%ebp)
c0106be6:	74 08                	je     c0106bf0 <get_pgtable_items+0xa6>
            *right_store = start;// 记录右边界索引
c0106be8:	8b 45 1c             	mov    0x1c(%ebp),%eax
c0106beb:	8b 55 10             	mov    0x10(%ebp),%edx
c0106bee:	89 10                	mov    %edx,(%eax)
        }
        return perm;// 返回用户权限位
c0106bf0:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0106bf3:	eb 05                	jmp    c0106bfa <get_pgtable_items+0xb0>
    }
    return 0;// 如果未找到有效项，返回0
c0106bf5:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0106bfa:	89 ec                	mov    %ebp,%esp
c0106bfc:	5d                   	pop    %ebp
c0106bfd:	c3                   	ret    

c0106bfe <print_pgdir>:

//print_pgdir - print the PDT&PT
void
print_pgdir(void) {
c0106bfe:	55                   	push   %ebp
c0106bff:	89 e5                	mov    %esp,%ebp
c0106c01:	57                   	push   %edi
c0106c02:	56                   	push   %esi
c0106c03:	53                   	push   %ebx
c0106c04:	83 ec 4c             	sub    $0x4c,%esp
    cprintf("-------------------- BEGIN --------------------\n");
c0106c07:	c7 04 24 04 d4 10 c0 	movl   $0xc010d404,(%esp)
c0106c0e:	e8 65 97 ff ff       	call   c0100378 <cprintf>
    // 定义变量 left, right 和 perm
    size_t left, right = 0, perm;
c0106c13:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
    // 遍历页目录项
    while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) {
c0106c1a:	e9 f2 00 00 00       	jmp    c0106d11 <print_pgdir+0x113>
        // 打印页目录项的信息
        cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left,
c0106c1f:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106c22:	89 04 24             	mov    %eax,(%esp)
c0106c25:	e8 de fe ff ff       	call   c0106b08 <perm2str>
                left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm));
c0106c2a:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0106c2d:	8b 4d e0             	mov    -0x20(%ebp),%ecx
c0106c30:	29 ca                	sub    %ecx,%edx
        cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left,
c0106c32:	89 d6                	mov    %edx,%esi
c0106c34:	c1 e6 16             	shl    $0x16,%esi
c0106c37:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0106c3a:	89 d3                	mov    %edx,%ebx
c0106c3c:	c1 e3 16             	shl    $0x16,%ebx
c0106c3f:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0106c42:	89 d1                	mov    %edx,%ecx
c0106c44:	c1 e1 16             	shl    $0x16,%ecx
c0106c47:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0106c4a:	8b 7d e0             	mov    -0x20(%ebp),%edi
c0106c4d:	29 fa                	sub    %edi,%edx
c0106c4f:	89 44 24 14          	mov    %eax,0x14(%esp)
c0106c53:	89 74 24 10          	mov    %esi,0x10(%esp)
c0106c57:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c0106c5b:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0106c5f:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106c63:	c7 04 24 35 d4 10 c0 	movl   $0xc010d435,(%esp)
c0106c6a:	e8 09 97 ff ff       	call   c0100378 <cprintf>
        // 计算页表项的起始和结束索引
        size_t l, r = left * NPTEENTRY;
c0106c6f:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0106c72:	c1 e0 0a             	shl    $0xa,%eax
c0106c75:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        // 遍历页表项
        while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) {
c0106c78:	eb 50                	jmp    c0106cca <print_pgdir+0xcc>
            // 打印页表项的信息
            cprintf("  |-- PTE(%05x) %08x-%08x %08x %s\n", r - l,
c0106c7a:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106c7d:	89 04 24             	mov    %eax,(%esp)
c0106c80:	e8 83 fe ff ff       	call   c0106b08 <perm2str>
                    l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm));
c0106c85:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0106c88:	8b 4d d8             	mov    -0x28(%ebp),%ecx
c0106c8b:	29 ca                	sub    %ecx,%edx
            cprintf("  |-- PTE(%05x) %08x-%08x %08x %s\n", r - l,
c0106c8d:	89 d6                	mov    %edx,%esi
c0106c8f:	c1 e6 0c             	shl    $0xc,%esi
c0106c92:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0106c95:	89 d3                	mov    %edx,%ebx
c0106c97:	c1 e3 0c             	shl    $0xc,%ebx
c0106c9a:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0106c9d:	89 d1                	mov    %edx,%ecx
c0106c9f:	c1 e1 0c             	shl    $0xc,%ecx
c0106ca2:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0106ca5:	8b 7d d8             	mov    -0x28(%ebp),%edi
c0106ca8:	29 fa                	sub    %edi,%edx
c0106caa:	89 44 24 14          	mov    %eax,0x14(%esp)
c0106cae:	89 74 24 10          	mov    %esi,0x10(%esp)
c0106cb2:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c0106cb6:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0106cba:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106cbe:	c7 04 24 54 d4 10 c0 	movl   $0xc010d454,(%esp)
c0106cc5:	e8 ae 96 ff ff       	call   c0100378 <cprintf>
        while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) {
c0106cca:	be 00 00 c0 fa       	mov    $0xfac00000,%esi
c0106ccf:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0106cd2:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0106cd5:	89 d3                	mov    %edx,%ebx
c0106cd7:	c1 e3 0a             	shl    $0xa,%ebx
c0106cda:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0106cdd:	89 d1                	mov    %edx,%ecx
c0106cdf:	c1 e1 0a             	shl    $0xa,%ecx
c0106ce2:	8d 55 d4             	lea    -0x2c(%ebp),%edx
c0106ce5:	89 54 24 14          	mov    %edx,0x14(%esp)
c0106ce9:	8d 55 d8             	lea    -0x28(%ebp),%edx
c0106cec:	89 54 24 10          	mov    %edx,0x10(%esp)
c0106cf0:	89 74 24 0c          	mov    %esi,0xc(%esp)
c0106cf4:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106cf8:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c0106cfc:	89 0c 24             	mov    %ecx,(%esp)
c0106cff:	e8 46 fe ff ff       	call   c0106b4a <get_pgtable_items>
c0106d04:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0106d07:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0106d0b:	0f 85 69 ff ff ff    	jne    c0106c7a <print_pgdir+0x7c>
    while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) {
c0106d11:	b9 00 b0 fe fa       	mov    $0xfafeb000,%ecx
c0106d16:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0106d19:	8d 55 dc             	lea    -0x24(%ebp),%edx
c0106d1c:	89 54 24 14          	mov    %edx,0x14(%esp)
c0106d20:	8d 55 e0             	lea    -0x20(%ebp),%edx
c0106d23:	89 54 24 10          	mov    %edx,0x10(%esp)
c0106d27:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c0106d2b:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106d2f:	c7 44 24 04 00 04 00 	movl   $0x400,0x4(%esp)
c0106d36:	00 
c0106d37:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0106d3e:	e8 07 fe ff ff       	call   c0106b4a <get_pgtable_items>
c0106d43:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0106d46:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0106d4a:	0f 85 cf fe ff ff    	jne    c0106c1f <print_pgdir+0x21>
        }
    }
    cprintf("--------------------- END ---------------------\n");
c0106d50:	c7 04 24 78 d4 10 c0 	movl   $0xc010d478,(%esp)
c0106d57:	e8 1c 96 ff ff       	call   c0100378 <cprintf>
}
c0106d5c:	90                   	nop
c0106d5d:	83 c4 4c             	add    $0x4c,%esp
c0106d60:	5b                   	pop    %ebx
c0106d61:	5e                   	pop    %esi
c0106d62:	5f                   	pop    %edi
c0106d63:	5d                   	pop    %ebp
c0106d64:	c3                   	ret    

c0106d65 <pa2page>:
pa2page(uintptr_t pa) {
c0106d65:	55                   	push   %ebp
c0106d66:	89 e5                	mov    %esp,%ebp
c0106d68:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c0106d6b:	8b 45 08             	mov    0x8(%ebp),%eax
c0106d6e:	c1 e8 0c             	shr    $0xc,%eax
c0106d71:	89 c2                	mov    %eax,%edx
c0106d73:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0106d78:	39 c2                	cmp    %eax,%edx
c0106d7a:	72 1c                	jb     c0106d98 <pa2page+0x33>
        panic("pa2page called with invalid pa");
c0106d7c:	c7 44 24 08 ac d4 10 	movl   $0xc010d4ac,0x8(%esp)
c0106d83:	c0 
c0106d84:	c7 44 24 04 5e 00 00 	movl   $0x5e,0x4(%esp)
c0106d8b:	00 
c0106d8c:	c7 04 24 cb d4 10 c0 	movl   $0xc010d4cb,(%esp)
c0106d93:	e8 a3 9f ff ff       	call   c0100d3b <__panic>
    return &pages[PPN(pa)];
c0106d98:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c0106d9e:	8b 45 08             	mov    0x8(%ebp),%eax
c0106da1:	c1 e8 0c             	shr    $0xc,%eax
c0106da4:	c1 e0 05             	shl    $0x5,%eax
c0106da7:	01 d0                	add    %edx,%eax
}
c0106da9:	89 ec                	mov    %ebp,%esp
c0106dab:	5d                   	pop    %ebp
c0106dac:	c3                   	ret    

c0106dad <pte2page>:
pte2page(pte_t pte) {
c0106dad:	55                   	push   %ebp
c0106dae:	89 e5                	mov    %esp,%ebp
c0106db0:	83 ec 18             	sub    $0x18,%esp
    if (!(pte & PTE_P)) {
c0106db3:	8b 45 08             	mov    0x8(%ebp),%eax
c0106db6:	83 e0 01             	and    $0x1,%eax
c0106db9:	85 c0                	test   %eax,%eax
c0106dbb:	75 1c                	jne    c0106dd9 <pte2page+0x2c>
        panic("pte2page called with invalid pte");
c0106dbd:	c7 44 24 08 dc d4 10 	movl   $0xc010d4dc,0x8(%esp)
c0106dc4:	c0 
c0106dc5:	c7 44 24 04 70 00 00 	movl   $0x70,0x4(%esp)
c0106dcc:	00 
c0106dcd:	c7 04 24 cb d4 10 c0 	movl   $0xc010d4cb,(%esp)
c0106dd4:	e8 62 9f ff ff       	call   c0100d3b <__panic>
    return pa2page(PTE_ADDR(pte));
c0106dd9:	8b 45 08             	mov    0x8(%ebp),%eax
c0106ddc:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0106de1:	89 04 24             	mov    %eax,(%esp)
c0106de4:	e8 7c ff ff ff       	call   c0106d65 <pa2page>
}
c0106de9:	89 ec                	mov    %ebp,%esp
c0106deb:	5d                   	pop    %ebp
c0106dec:	c3                   	ret    

c0106ded <pde2page>:
pde2page(pde_t pde) {
c0106ded:	55                   	push   %ebp
c0106dee:	89 e5                	mov    %esp,%ebp
c0106df0:	83 ec 18             	sub    $0x18,%esp
    return pa2page(PDE_ADDR(pde));
c0106df3:	8b 45 08             	mov    0x8(%ebp),%eax
c0106df6:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0106dfb:	89 04 24             	mov    %eax,(%esp)
c0106dfe:	e8 62 ff ff ff       	call   c0106d65 <pa2page>
}
c0106e03:	89 ec                	mov    %ebp,%esp
c0106e05:	5d                   	pop    %ebp
c0106e06:	c3                   	ret    

c0106e07 <swap_init>:

static void check_swap(void);

int
swap_init(void)
{
c0106e07:	55                   	push   %ebp
c0106e08:	89 e5                	mov    %esp,%ebp
c0106e0a:	83 ec 28             	sub    $0x28,%esp
     swapfs_init();
c0106e0d:	e8 ee 23 00 00       	call   c0109200 <swapfs_init>

     if (!(1024 <= max_swap_offset && max_swap_offset < MAX_SWAP_OFFSET_LIMIT))
c0106e12:	a1 40 40 1a c0       	mov    0xc01a4040,%eax
c0106e17:	3d ff 03 00 00       	cmp    $0x3ff,%eax
c0106e1c:	76 0c                	jbe    c0106e2a <swap_init+0x23>
c0106e1e:	a1 40 40 1a c0       	mov    0xc01a4040,%eax
c0106e23:	3d ff ff ff 00       	cmp    $0xffffff,%eax
c0106e28:	76 25                	jbe    c0106e4f <swap_init+0x48>
     {
          panic("bad max_swap_offset %08x.\n", max_swap_offset);
c0106e2a:	a1 40 40 1a c0       	mov    0xc01a4040,%eax
c0106e2f:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0106e33:	c7 44 24 08 fd d4 10 	movl   $0xc010d4fd,0x8(%esp)
c0106e3a:	c0 
c0106e3b:	c7 44 24 04 27 00 00 	movl   $0x27,0x4(%esp)
c0106e42:	00 
c0106e43:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0106e4a:	e8 ec 9e ff ff       	call   c0100d3b <__panic>
     }
     

     sm = &swap_manager_fifo;
c0106e4f:	c7 05 00 41 1a c0 60 	movl   $0xc012fa60,0xc01a4100
c0106e56:	fa 12 c0 
     int r = sm->init();
c0106e59:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0106e5e:	8b 40 04             	mov    0x4(%eax),%eax
c0106e61:	ff d0                	call   *%eax
c0106e63:	89 45 f4             	mov    %eax,-0xc(%ebp)
     
     if (r == 0)
c0106e66:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0106e6a:	75 26                	jne    c0106e92 <swap_init+0x8b>
     {
          swap_init_ok = 1;
c0106e6c:	c7 05 44 40 1a c0 01 	movl   $0x1,0xc01a4044
c0106e73:	00 00 00 
          cprintf("SWAP: manager = %s\n", sm->name);
c0106e76:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0106e7b:	8b 00                	mov    (%eax),%eax
c0106e7d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106e81:	c7 04 24 27 d5 10 c0 	movl   $0xc010d527,(%esp)
c0106e88:	e8 eb 94 ff ff       	call   c0100378 <cprintf>
          check_swap();
c0106e8d:	e8 b0 04 00 00       	call   c0107342 <check_swap>
     }

     return r;
c0106e92:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0106e95:	89 ec                	mov    %ebp,%esp
c0106e97:	5d                   	pop    %ebp
c0106e98:	c3                   	ret    

c0106e99 <swap_init_mm>:

int
swap_init_mm(struct mm_struct *mm)
{
c0106e99:	55                   	push   %ebp
c0106e9a:	89 e5                	mov    %esp,%ebp
c0106e9c:	83 ec 18             	sub    $0x18,%esp
     return sm->init_mm(mm);
c0106e9f:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0106ea4:	8b 40 08             	mov    0x8(%eax),%eax
c0106ea7:	8b 55 08             	mov    0x8(%ebp),%edx
c0106eaa:	89 14 24             	mov    %edx,(%esp)
c0106ead:	ff d0                	call   *%eax
}
c0106eaf:	89 ec                	mov    %ebp,%esp
c0106eb1:	5d                   	pop    %ebp
c0106eb2:	c3                   	ret    

c0106eb3 <swap_tick_event>:

int
swap_tick_event(struct mm_struct *mm)
{
c0106eb3:	55                   	push   %ebp
c0106eb4:	89 e5                	mov    %esp,%ebp
c0106eb6:	83 ec 18             	sub    $0x18,%esp
     return sm->tick_event(mm);
c0106eb9:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0106ebe:	8b 40 0c             	mov    0xc(%eax),%eax
c0106ec1:	8b 55 08             	mov    0x8(%ebp),%edx
c0106ec4:	89 14 24             	mov    %edx,(%esp)
c0106ec7:	ff d0                	call   *%eax
}
c0106ec9:	89 ec                	mov    %ebp,%esp
c0106ecb:	5d                   	pop    %ebp
c0106ecc:	c3                   	ret    

c0106ecd <swap_map_swappable>:

int
swap_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
{
c0106ecd:	55                   	push   %ebp
c0106ece:	89 e5                	mov    %esp,%ebp
c0106ed0:	83 ec 18             	sub    $0x18,%esp
     return sm->map_swappable(mm, addr, page, swap_in);
c0106ed3:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0106ed8:	8b 40 10             	mov    0x10(%eax),%eax
c0106edb:	8b 55 14             	mov    0x14(%ebp),%edx
c0106ede:	89 54 24 0c          	mov    %edx,0xc(%esp)
c0106ee2:	8b 55 10             	mov    0x10(%ebp),%edx
c0106ee5:	89 54 24 08          	mov    %edx,0x8(%esp)
c0106ee9:	8b 55 0c             	mov    0xc(%ebp),%edx
c0106eec:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106ef0:	8b 55 08             	mov    0x8(%ebp),%edx
c0106ef3:	89 14 24             	mov    %edx,(%esp)
c0106ef6:	ff d0                	call   *%eax
}
c0106ef8:	89 ec                	mov    %ebp,%esp
c0106efa:	5d                   	pop    %ebp
c0106efb:	c3                   	ret    

c0106efc <swap_set_unswappable>:

int
swap_set_unswappable(struct mm_struct *mm, uintptr_t addr)
{
c0106efc:	55                   	push   %ebp
c0106efd:	89 e5                	mov    %esp,%ebp
c0106eff:	83 ec 18             	sub    $0x18,%esp
     return sm->set_unswappable(mm, addr);
c0106f02:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0106f07:	8b 40 14             	mov    0x14(%eax),%eax
c0106f0a:	8b 55 0c             	mov    0xc(%ebp),%edx
c0106f0d:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106f11:	8b 55 08             	mov    0x8(%ebp),%edx
c0106f14:	89 14 24             	mov    %edx,(%esp)
c0106f17:	ff d0                	call   *%eax
}
c0106f19:	89 ec                	mov    %ebp,%esp
c0106f1b:	5d                   	pop    %ebp
c0106f1c:	c3                   	ret    

c0106f1d <swap_out>:

volatile unsigned int swap_out_num=0;

int
swap_out(struct mm_struct *mm, int n, int in_tick)
{
c0106f1d:	55                   	push   %ebp
c0106f1e:	89 e5                	mov    %esp,%ebp
c0106f20:	83 ec 38             	sub    $0x38,%esp
     int i;
     for (i = 0; i != n; ++ i)
c0106f23:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0106f2a:	e9 53 01 00 00       	jmp    c0107082 <swap_out+0x165>
     {
          uintptr_t v;
          //struct Page **ptr_page=NULL;
          struct Page *page;
          // cprintf("i %d, SWAP: call swap_out_victim\n",i);
          int r = sm->swap_out_victim(mm, &page, in_tick);
c0106f2f:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0106f34:	8b 40 18             	mov    0x18(%eax),%eax
c0106f37:	8b 55 10             	mov    0x10(%ebp),%edx
c0106f3a:	89 54 24 08          	mov    %edx,0x8(%esp)
c0106f3e:	8d 55 e4             	lea    -0x1c(%ebp),%edx
c0106f41:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106f45:	8b 55 08             	mov    0x8(%ebp),%edx
c0106f48:	89 14 24             	mov    %edx,(%esp)
c0106f4b:	ff d0                	call   *%eax
c0106f4d:	89 45 f0             	mov    %eax,-0x10(%ebp)
          if (r != 0) {
c0106f50:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0106f54:	74 18                	je     c0106f6e <swap_out+0x51>
                    cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
c0106f56:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106f59:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106f5d:	c7 04 24 3c d5 10 c0 	movl   $0xc010d53c,(%esp)
c0106f64:	e8 0f 94 ff ff       	call   c0100378 <cprintf>
c0106f69:	e9 20 01 00 00       	jmp    c010708e <swap_out+0x171>
          }          
          //assert(!PageReserved(page));

          //cprintf("SWAP: choose victim page 0x%08x\n", page);
          
          v=page->pra_vaddr; 
c0106f6e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106f71:	8b 40 1c             	mov    0x1c(%eax),%eax
c0106f74:	89 45 ec             	mov    %eax,-0x14(%ebp)
          pte_t *ptep = get_pte(mm->pgdir, v, 0);
c0106f77:	8b 45 08             	mov    0x8(%ebp),%eax
c0106f7a:	8b 40 0c             	mov    0xc(%eax),%eax
c0106f7d:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0106f84:	00 
c0106f85:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0106f88:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106f8c:	89 04 24             	mov    %eax,(%esp)
c0106f8f:	e8 a8 e8 ff ff       	call   c010583c <get_pte>
c0106f94:	89 45 e8             	mov    %eax,-0x18(%ebp)
          assert((*ptep & PTE_P) != 0);
c0106f97:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106f9a:	8b 00                	mov    (%eax),%eax
c0106f9c:	83 e0 01             	and    $0x1,%eax
c0106f9f:	85 c0                	test   %eax,%eax
c0106fa1:	75 24                	jne    c0106fc7 <swap_out+0xaa>
c0106fa3:	c7 44 24 0c 69 d5 10 	movl   $0xc010d569,0xc(%esp)
c0106faa:	c0 
c0106fab:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0106fb2:	c0 
c0106fb3:	c7 44 24 04 67 00 00 	movl   $0x67,0x4(%esp)
c0106fba:	00 
c0106fbb:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0106fc2:	e8 74 9d ff ff       	call   c0100d3b <__panic>

          if (swapfs_write( (page->pra_vaddr/PGSIZE+1)<<8, page) != 0) {
c0106fc7:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106fca:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0106fcd:	8b 52 1c             	mov    0x1c(%edx),%edx
c0106fd0:	c1 ea 0c             	shr    $0xc,%edx
c0106fd3:	42                   	inc    %edx
c0106fd4:	c1 e2 08             	shl    $0x8,%edx
c0106fd7:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106fdb:	89 14 24             	mov    %edx,(%esp)
c0106fde:	e8 dc 22 00 00       	call   c01092bf <swapfs_write>
c0106fe3:	85 c0                	test   %eax,%eax
c0106fe5:	74 34                	je     c010701b <swap_out+0xfe>
                    cprintf("SWAP: failed to save\n");
c0106fe7:	c7 04 24 93 d5 10 c0 	movl   $0xc010d593,(%esp)
c0106fee:	e8 85 93 ff ff       	call   c0100378 <cprintf>
                    sm->map_swappable(mm, v, page, 0);
c0106ff3:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0106ff8:	8b 40 10             	mov    0x10(%eax),%eax
c0106ffb:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0106ffe:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0107005:	00 
c0107006:	89 54 24 08          	mov    %edx,0x8(%esp)
c010700a:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010700d:	89 54 24 04          	mov    %edx,0x4(%esp)
c0107011:	8b 55 08             	mov    0x8(%ebp),%edx
c0107014:	89 14 24             	mov    %edx,(%esp)
c0107017:	ff d0                	call   *%eax
c0107019:	eb 64                	jmp    c010707f <swap_out+0x162>
                    continue;
          }
          else {
                    cprintf("swap_out: i %d, store page in vaddr 0x%x to disk swap entry %d\n", i, v, page->pra_vaddr/PGSIZE+1);
c010701b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010701e:	8b 40 1c             	mov    0x1c(%eax),%eax
c0107021:	c1 e8 0c             	shr    $0xc,%eax
c0107024:	40                   	inc    %eax
c0107025:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0107029:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010702c:	89 44 24 08          	mov    %eax,0x8(%esp)
c0107030:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107033:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107037:	c7 04 24 ac d5 10 c0 	movl   $0xc010d5ac,(%esp)
c010703e:	e8 35 93 ff ff       	call   c0100378 <cprintf>
                    *ptep = (page->pra_vaddr/PGSIZE+1)<<8;
c0107043:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107046:	8b 40 1c             	mov    0x1c(%eax),%eax
c0107049:	c1 e8 0c             	shr    $0xc,%eax
c010704c:	40                   	inc    %eax
c010704d:	c1 e0 08             	shl    $0x8,%eax
c0107050:	89 c2                	mov    %eax,%edx
c0107052:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107055:	89 10                	mov    %edx,(%eax)
                    free_page(page);
c0107057:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010705a:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107061:	00 
c0107062:	89 04 24             	mov    %eax,(%esp)
c0107065:	e8 84 e1 ff ff       	call   c01051ee <free_pages>
          }
          
          tlb_invalidate(mm->pgdir, v);
c010706a:	8b 45 08             	mov    0x8(%ebp),%eax
c010706d:	8b 40 0c             	mov    0xc(%eax),%eax
c0107070:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0107073:	89 54 24 04          	mov    %edx,0x4(%esp)
c0107077:	89 04 24             	mov    %eax,(%esp)
c010707a:	e8 df ee ff ff       	call   c0105f5e <tlb_invalidate>
     for (i = 0; i != n; ++ i)
c010707f:	ff 45 f4             	incl   -0xc(%ebp)
c0107082:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107085:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0107088:	0f 85 a1 fe ff ff    	jne    c0106f2f <swap_out+0x12>
     }
     return i;
c010708e:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0107091:	89 ec                	mov    %ebp,%esp
c0107093:	5d                   	pop    %ebp
c0107094:	c3                   	ret    

c0107095 <swap_in>:

int
swap_in(struct mm_struct *mm, uintptr_t addr, struct Page **ptr_result)
{
c0107095:	55                   	push   %ebp
c0107096:	89 e5                	mov    %esp,%ebp
c0107098:	83 ec 28             	sub    $0x28,%esp
     struct Page *result = alloc_page();
c010709b:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01070a2:	e8 da e0 ff ff       	call   c0105181 <alloc_pages>
c01070a7:	89 45 f4             	mov    %eax,-0xc(%ebp)
     assert(result!=NULL);
c01070aa:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01070ae:	75 24                	jne    c01070d4 <swap_in+0x3f>
c01070b0:	c7 44 24 0c ec d5 10 	movl   $0xc010d5ec,0xc(%esp)
c01070b7:	c0 
c01070b8:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01070bf:	c0 
c01070c0:	c7 44 24 04 7d 00 00 	movl   $0x7d,0x4(%esp)
c01070c7:	00 
c01070c8:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01070cf:	e8 67 9c ff ff       	call   c0100d3b <__panic>

     pte_t *ptep = get_pte(mm->pgdir, addr, 0);
c01070d4:	8b 45 08             	mov    0x8(%ebp),%eax
c01070d7:	8b 40 0c             	mov    0xc(%eax),%eax
c01070da:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01070e1:	00 
c01070e2:	8b 55 0c             	mov    0xc(%ebp),%edx
c01070e5:	89 54 24 04          	mov    %edx,0x4(%esp)
c01070e9:	89 04 24             	mov    %eax,(%esp)
c01070ec:	e8 4b e7 ff ff       	call   c010583c <get_pte>
c01070f1:	89 45 f0             	mov    %eax,-0x10(%ebp)
     // cprintf("SWAP: load ptep %x swap entry %d to vaddr 0x%08x, page %x, No %d\n", ptep, (*ptep)>>8, addr, result, (result-pages));
    
     int r;
     if ((r = swapfs_read((*ptep), result)) != 0)
c01070f4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01070f7:	8b 00                	mov    (%eax),%eax
c01070f9:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01070fc:	89 54 24 04          	mov    %edx,0x4(%esp)
c0107100:	89 04 24             	mov    %eax,(%esp)
c0107103:	e8 43 21 00 00       	call   c010924b <swapfs_read>
c0107108:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010710b:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c010710f:	74 2a                	je     c010713b <swap_in+0xa6>
     {
        assert(r!=0);
c0107111:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0107115:	75 24                	jne    c010713b <swap_in+0xa6>
c0107117:	c7 44 24 0c f9 d5 10 	movl   $0xc010d5f9,0xc(%esp)
c010711e:	c0 
c010711f:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107126:	c0 
c0107127:	c7 44 24 04 85 00 00 	movl   $0x85,0x4(%esp)
c010712e:	00 
c010712f:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107136:	e8 00 9c ff ff       	call   c0100d3b <__panic>
     }
     cprintf("swap_in: load disk swap entry %d with swap_page in vadr 0x%x\n", (*ptep)>>8, addr);
c010713b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010713e:	8b 00                	mov    (%eax),%eax
c0107140:	c1 e8 08             	shr    $0x8,%eax
c0107143:	89 c2                	mov    %eax,%edx
c0107145:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107148:	89 44 24 08          	mov    %eax,0x8(%esp)
c010714c:	89 54 24 04          	mov    %edx,0x4(%esp)
c0107150:	c7 04 24 00 d6 10 c0 	movl   $0xc010d600,(%esp)
c0107157:	e8 1c 92 ff ff       	call   c0100378 <cprintf>
     *ptr_result=result;
c010715c:	8b 45 10             	mov    0x10(%ebp),%eax
c010715f:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0107162:	89 10                	mov    %edx,(%eax)
     return 0;
c0107164:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0107169:	89 ec                	mov    %ebp,%esp
c010716b:	5d                   	pop    %ebp
c010716c:	c3                   	ret    

c010716d <check_content_set>:



static inline void
check_content_set(void)
{
c010716d:	55                   	push   %ebp
c010716e:	89 e5                	mov    %esp,%ebp
c0107170:	83 ec 18             	sub    $0x18,%esp
     *(unsigned char *)0x1000 = 0x0a;
c0107173:	b8 00 10 00 00       	mov    $0x1000,%eax
c0107178:	c6 00 0a             	movb   $0xa,(%eax)
     assert(pgfault_num==1);
c010717b:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107180:	83 f8 01             	cmp    $0x1,%eax
c0107183:	74 24                	je     c01071a9 <check_content_set+0x3c>
c0107185:	c7 44 24 0c 3e d6 10 	movl   $0xc010d63e,0xc(%esp)
c010718c:	c0 
c010718d:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107194:	c0 
c0107195:	c7 44 24 04 92 00 00 	movl   $0x92,0x4(%esp)
c010719c:	00 
c010719d:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01071a4:	e8 92 9b ff ff       	call   c0100d3b <__panic>
     *(unsigned char *)0x1010 = 0x0a;
c01071a9:	b8 10 10 00 00       	mov    $0x1010,%eax
c01071ae:	c6 00 0a             	movb   $0xa,(%eax)
     assert(pgfault_num==1);
c01071b1:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c01071b6:	83 f8 01             	cmp    $0x1,%eax
c01071b9:	74 24                	je     c01071df <check_content_set+0x72>
c01071bb:	c7 44 24 0c 3e d6 10 	movl   $0xc010d63e,0xc(%esp)
c01071c2:	c0 
c01071c3:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01071ca:	c0 
c01071cb:	c7 44 24 04 94 00 00 	movl   $0x94,0x4(%esp)
c01071d2:	00 
c01071d3:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01071da:	e8 5c 9b ff ff       	call   c0100d3b <__panic>
     *(unsigned char *)0x2000 = 0x0b;
c01071df:	b8 00 20 00 00       	mov    $0x2000,%eax
c01071e4:	c6 00 0b             	movb   $0xb,(%eax)
     assert(pgfault_num==2);
c01071e7:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c01071ec:	83 f8 02             	cmp    $0x2,%eax
c01071ef:	74 24                	je     c0107215 <check_content_set+0xa8>
c01071f1:	c7 44 24 0c 4d d6 10 	movl   $0xc010d64d,0xc(%esp)
c01071f8:	c0 
c01071f9:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107200:	c0 
c0107201:	c7 44 24 04 96 00 00 	movl   $0x96,0x4(%esp)
c0107208:	00 
c0107209:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107210:	e8 26 9b ff ff       	call   c0100d3b <__panic>
     *(unsigned char *)0x2010 = 0x0b;
c0107215:	b8 10 20 00 00       	mov    $0x2010,%eax
c010721a:	c6 00 0b             	movb   $0xb,(%eax)
     assert(pgfault_num==2);
c010721d:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107222:	83 f8 02             	cmp    $0x2,%eax
c0107225:	74 24                	je     c010724b <check_content_set+0xde>
c0107227:	c7 44 24 0c 4d d6 10 	movl   $0xc010d64d,0xc(%esp)
c010722e:	c0 
c010722f:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107236:	c0 
c0107237:	c7 44 24 04 98 00 00 	movl   $0x98,0x4(%esp)
c010723e:	00 
c010723f:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107246:	e8 f0 9a ff ff       	call   c0100d3b <__panic>
     *(unsigned char *)0x3000 = 0x0c;
c010724b:	b8 00 30 00 00       	mov    $0x3000,%eax
c0107250:	c6 00 0c             	movb   $0xc,(%eax)
     assert(pgfault_num==3);
c0107253:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107258:	83 f8 03             	cmp    $0x3,%eax
c010725b:	74 24                	je     c0107281 <check_content_set+0x114>
c010725d:	c7 44 24 0c 5c d6 10 	movl   $0xc010d65c,0xc(%esp)
c0107264:	c0 
c0107265:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c010726c:	c0 
c010726d:	c7 44 24 04 9a 00 00 	movl   $0x9a,0x4(%esp)
c0107274:	00 
c0107275:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c010727c:	e8 ba 9a ff ff       	call   c0100d3b <__panic>
     *(unsigned char *)0x3010 = 0x0c;
c0107281:	b8 10 30 00 00       	mov    $0x3010,%eax
c0107286:	c6 00 0c             	movb   $0xc,(%eax)
     assert(pgfault_num==3);
c0107289:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c010728e:	83 f8 03             	cmp    $0x3,%eax
c0107291:	74 24                	je     c01072b7 <check_content_set+0x14a>
c0107293:	c7 44 24 0c 5c d6 10 	movl   $0xc010d65c,0xc(%esp)
c010729a:	c0 
c010729b:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01072a2:	c0 
c01072a3:	c7 44 24 04 9c 00 00 	movl   $0x9c,0x4(%esp)
c01072aa:	00 
c01072ab:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01072b2:	e8 84 9a ff ff       	call   c0100d3b <__panic>
     *(unsigned char *)0x4000 = 0x0d;
c01072b7:	b8 00 40 00 00       	mov    $0x4000,%eax
c01072bc:	c6 00 0d             	movb   $0xd,(%eax)
     assert(pgfault_num==4);
c01072bf:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c01072c4:	83 f8 04             	cmp    $0x4,%eax
c01072c7:	74 24                	je     c01072ed <check_content_set+0x180>
c01072c9:	c7 44 24 0c 6b d6 10 	movl   $0xc010d66b,0xc(%esp)
c01072d0:	c0 
c01072d1:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01072d8:	c0 
c01072d9:	c7 44 24 04 9e 00 00 	movl   $0x9e,0x4(%esp)
c01072e0:	00 
c01072e1:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01072e8:	e8 4e 9a ff ff       	call   c0100d3b <__panic>
     *(unsigned char *)0x4010 = 0x0d;
c01072ed:	b8 10 40 00 00       	mov    $0x4010,%eax
c01072f2:	c6 00 0d             	movb   $0xd,(%eax)
     assert(pgfault_num==4);
c01072f5:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c01072fa:	83 f8 04             	cmp    $0x4,%eax
c01072fd:	74 24                	je     c0107323 <check_content_set+0x1b6>
c01072ff:	c7 44 24 0c 6b d6 10 	movl   $0xc010d66b,0xc(%esp)
c0107306:	c0 
c0107307:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c010730e:	c0 
c010730f:	c7 44 24 04 a0 00 00 	movl   $0xa0,0x4(%esp)
c0107316:	00 
c0107317:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c010731e:	e8 18 9a ff ff       	call   c0100d3b <__panic>
}
c0107323:	90                   	nop
c0107324:	89 ec                	mov    %ebp,%esp
c0107326:	5d                   	pop    %ebp
c0107327:	c3                   	ret    

c0107328 <check_content_access>:

static inline int
check_content_access(void)
{
c0107328:	55                   	push   %ebp
c0107329:	89 e5                	mov    %esp,%ebp
c010732b:	83 ec 18             	sub    $0x18,%esp
    int ret = sm->check_swap();
c010732e:	a1 00 41 1a c0       	mov    0xc01a4100,%eax
c0107333:	8b 40 1c             	mov    0x1c(%eax),%eax
c0107336:	ff d0                	call   *%eax
c0107338:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return ret;
c010733b:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010733e:	89 ec                	mov    %ebp,%esp
c0107340:	5d                   	pop    %ebp
c0107341:	c3                   	ret    

c0107342 <check_swap>:

#define free_list (free_area.free_list)
#define nr_free (free_area.nr_free)

check_swap(void)
{
c0107342:	55                   	push   %ebp
c0107343:	89 e5                	mov    %esp,%ebp
c0107345:	83 ec 78             	sub    $0x78,%esp
    //backup mem env// 备份内存环境，确保检查后没有页面丢失
     int ret, count = 0, total = 0, i;
c0107348:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c010734f:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
     list_entry_t *le = &free_list;
c0107356:	c7 45 e8 84 3f 1a c0 	movl   $0xc01a3f84,-0x18(%ebp)
     while ((le = list_next(le)) != &free_list) {
c010735d:	eb 6a                	jmp    c01073c9 <check_swap+0x87>
        struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构
c010735f:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107362:	83 e8 0c             	sub    $0xc,%eax
c0107365:	89 45 c8             	mov    %eax,-0x38(%ebp)
        assert(PageProperty(p));// 断言页面属性有效
c0107368:	8b 45 c8             	mov    -0x38(%ebp),%eax
c010736b:	83 c0 04             	add    $0x4,%eax
c010736e:	c7 45 c4 01 00 00 00 	movl   $0x1,-0x3c(%ebp)
c0107375:	89 45 c0             	mov    %eax,-0x40(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0107378:	8b 45 c0             	mov    -0x40(%ebp),%eax
c010737b:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c010737e:	0f a3 10             	bt     %edx,(%eax)
c0107381:	19 c0                	sbb    %eax,%eax
c0107383:	89 45 bc             	mov    %eax,-0x44(%ebp)
    return oldbit != 0;
c0107386:	83 7d bc 00          	cmpl   $0x0,-0x44(%ebp)
c010738a:	0f 95 c0             	setne  %al
c010738d:	0f b6 c0             	movzbl %al,%eax
c0107390:	85 c0                	test   %eax,%eax
c0107392:	75 24                	jne    c01073b8 <check_swap+0x76>
c0107394:	c7 44 24 0c 7a d6 10 	movl   $0xc010d67a,0xc(%esp)
c010739b:	c0 
c010739c:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01073a3:	c0 
c01073a4:	c7 44 24 04 ba 00 00 	movl   $0xba,0x4(%esp)
c01073ab:	00 
c01073ac:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01073b3:	e8 83 99 ff ff       	call   c0100d3b <__panic>
        count ++, total += p->property;// 统计页面数量和属性总和
c01073b8:	ff 45 f4             	incl   -0xc(%ebp)
c01073bb:	8b 45 c8             	mov    -0x38(%ebp),%eax
c01073be:	8b 50 08             	mov    0x8(%eax),%edx
c01073c1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01073c4:	01 d0                	add    %edx,%eax
c01073c6:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01073c9:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01073cc:	89 45 b8             	mov    %eax,-0x48(%ebp)
c01073cf:	8b 45 b8             	mov    -0x48(%ebp),%eax
c01073d2:	8b 40 04             	mov    0x4(%eax),%eax
     while ((le = list_next(le)) != &free_list) {
c01073d5:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01073d8:	81 7d e8 84 3f 1a c0 	cmpl   $0xc01a3f84,-0x18(%ebp)
c01073df:	0f 85 7a ff ff ff    	jne    c010735f <check_swap+0x1d>
     }
     assert(total == nr_free_pages());// 断言统计的属性总和与空闲页面数一致
c01073e5:	e8 39 de ff ff       	call   c0105223 <nr_free_pages>
c01073ea:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01073ed:	39 d0                	cmp    %edx,%eax
c01073ef:	74 24                	je     c0107415 <check_swap+0xd3>
c01073f1:	c7 44 24 0c 8a d6 10 	movl   $0xc010d68a,0xc(%esp)
c01073f8:	c0 
c01073f9:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107400:	c0 
c0107401:	c7 44 24 04 bd 00 00 	movl   $0xbd,0x4(%esp)
c0107408:	00 
c0107409:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107410:	e8 26 99 ff ff       	call   c0100d3b <__panic>
     cprintf("BEGIN check_swap: count %d, total %d\n",count,total);// 打印初始状态
c0107415:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107418:	89 44 24 08          	mov    %eax,0x8(%esp)
c010741c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010741f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107423:	c7 04 24 a4 d6 10 c0 	movl   $0xc010d6a4,(%esp)
c010742a:	e8 49 8f ff ff       	call   c0100378 <cprintf>
     
     //now we set the phy pages env // 设置物理页面环境    
     struct mm_struct *mm = mm_create();// 创建内存管理结构
c010742f:	e8 81 0b 00 00       	call   c0107fb5 <mm_create>
c0107434:	89 45 e4             	mov    %eax,-0x1c(%ebp)
     assert(mm != NULL); // 断言内存管理结构创建成功
c0107437:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c010743b:	75 24                	jne    c0107461 <check_swap+0x11f>
c010743d:	c7 44 24 0c ca d6 10 	movl   $0xc010d6ca,0xc(%esp)
c0107444:	c0 
c0107445:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c010744c:	c0 
c010744d:	c7 44 24 04 c2 00 00 	movl   $0xc2,0x4(%esp)
c0107454:	00 
c0107455:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c010745c:	e8 da 98 ff ff       	call   c0100d3b <__panic>

     extern struct mm_struct *check_mm_struct;// 声明外部变量
     assert(check_mm_struct == NULL);// 断言外部变量为空
c0107461:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c0107466:	85 c0                	test   %eax,%eax
c0107468:	74 24                	je     c010748e <check_swap+0x14c>
c010746a:	c7 44 24 0c d5 d6 10 	movl   $0xc010d6d5,0xc(%esp)
c0107471:	c0 
c0107472:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107479:	c0 
c010747a:	c7 44 24 04 c5 00 00 	movl   $0xc5,0x4(%esp)
c0107481:	00 
c0107482:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107489:	e8 ad 98 ff ff       	call   c0100d3b <__panic>

     // 将新创建的内存管理结构赋值给外部变量
     check_mm_struct = mm;
c010748e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107491:	a3 0c 41 1a c0       	mov    %eax,0xc01a410c

     pde_t *pgdir = mm->pgdir = boot_pgdir;// 设置页目录
c0107496:	8b 15 00 fa 12 c0    	mov    0xc012fa00,%edx
c010749c:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010749f:	89 50 0c             	mov    %edx,0xc(%eax)
c01074a2:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01074a5:	8b 40 0c             	mov    0xc(%eax),%eax
c01074a8:	89 45 e0             	mov    %eax,-0x20(%ebp)
     assert(pgdir[0] == 0);// 断言页目录的第一个条目为空
c01074ab:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01074ae:	8b 00                	mov    (%eax),%eax
c01074b0:	85 c0                	test   %eax,%eax
c01074b2:	74 24                	je     c01074d8 <check_swap+0x196>
c01074b4:	c7 44 24 0c ed d6 10 	movl   $0xc010d6ed,0xc(%esp)
c01074bb:	c0 
c01074bc:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01074c3:	c0 
c01074c4:	c7 44 24 04 cb 00 00 	movl   $0xcb,0x4(%esp)
c01074cb:	00 
c01074cc:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01074d3:	e8 63 98 ff ff       	call   c0100d3b <__panic>

     // 创建虚拟内存区域
     struct vma_struct *vma = vma_create(BEING_CHECK_VALID_VADDR, CHECK_VALID_VADDR, VM_WRITE | VM_READ);
c01074d8:	c7 44 24 08 03 00 00 	movl   $0x3,0x8(%esp)
c01074df:	00 
c01074e0:	c7 44 24 04 00 60 00 	movl   $0x6000,0x4(%esp)
c01074e7:	00 
c01074e8:	c7 04 24 00 10 00 00 	movl   $0x1000,(%esp)
c01074ef:	e8 5d 0b 00 00       	call   c0108051 <vma_create>
c01074f4:	89 45 dc             	mov    %eax,-0x24(%ebp)
     assert(vma != NULL);// 断言虚拟内存区域创建成功
c01074f7:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c01074fb:	75 24                	jne    c0107521 <check_swap+0x1df>
c01074fd:	c7 44 24 0c fb d6 10 	movl   $0xc010d6fb,0xc(%esp)
c0107504:	c0 
c0107505:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c010750c:	c0 
c010750d:	c7 44 24 04 cf 00 00 	movl   $0xcf,0x4(%esp)
c0107514:	00 
c0107515:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c010751c:	e8 1a 98 ff ff       	call   c0100d3b <__panic>

     // 插入虚拟内存区域到内存管理结构
     insert_vma_struct(mm, vma);
c0107521:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0107524:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107528:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010752b:	89 04 24             	mov    %eax,(%esp)
c010752e:	e8 b5 0c 00 00       	call   c01081e8 <insert_vma_struct>

     //setup the temp Page Table vaddr 0~4MB/ 设置临时页表，用于虚拟地址 0~4MB
     cprintf("setup Page Table for vaddr 0X1000, so alloc a page\n");// 打印设置页表的信息
c0107533:	c7 04 24 08 d7 10 c0 	movl   $0xc010d708,(%esp)
c010753a:	e8 39 8e ff ff       	call   c0100378 <cprintf>
     pte_t *temp_ptep=NULL;
c010753f:	c7 45 d8 00 00 00 00 	movl   $0x0,-0x28(%ebp)
     temp_ptep = get_pte(mm->pgdir, BEING_CHECK_VALID_VADDR, 1);// 获取页表项
c0107546:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107549:	8b 40 0c             	mov    0xc(%eax),%eax
c010754c:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c0107553:	00 
c0107554:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c010755b:	00 
c010755c:	89 04 24             	mov    %eax,(%esp)
c010755f:	e8 d8 e2 ff ff       	call   c010583c <get_pte>
c0107564:	89 45 d8             	mov    %eax,-0x28(%ebp)
     assert(temp_ptep!= NULL);// 断言获取页表项成功
c0107567:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c010756b:	75 24                	jne    c0107591 <check_swap+0x24f>
c010756d:	c7 44 24 0c 3c d7 10 	movl   $0xc010d73c,0xc(%esp)
c0107574:	c0 
c0107575:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c010757c:	c0 
c010757d:	c7 44 24 04 d8 00 00 	movl   $0xd8,0x4(%esp)
c0107584:	00 
c0107585:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c010758c:	e8 aa 97 ff ff       	call   c0100d3b <__panic>
     cprintf("setup Page Table vaddr 0~4MB OVER!\n");// 打印设置页表完成的信息
c0107591:	c7 04 24 50 d7 10 c0 	movl   $0xc010d750,(%esp)
c0107598:	e8 db 8d ff ff       	call   c0100378 <cprintf>
     
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c010759d:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c01075a4:	e9 a2 00 00 00       	jmp    c010764b <check_swap+0x309>
          check_rp[i] = alloc_page();// 分配页面
c01075a9:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01075b0:	e8 cc db ff ff       	call   c0105181 <alloc_pages>
c01075b5:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01075b8:	89 04 95 cc 40 1a c0 	mov    %eax,-0x3fe5bf34(,%edx,4)
          assert(check_rp[i] != NULL );// 断言分配页面成功
c01075bf:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01075c2:	8b 04 85 cc 40 1a c0 	mov    -0x3fe5bf34(,%eax,4),%eax
c01075c9:	85 c0                	test   %eax,%eax
c01075cb:	75 24                	jne    c01075f1 <check_swap+0x2af>
c01075cd:	c7 44 24 0c 74 d7 10 	movl   $0xc010d774,0xc(%esp)
c01075d4:	c0 
c01075d5:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01075dc:	c0 
c01075dd:	c7 44 24 04 dd 00 00 	movl   $0xdd,0x4(%esp)
c01075e4:	00 
c01075e5:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01075ec:	e8 4a 97 ff ff       	call   c0100d3b <__panic>
          assert(!PageProperty(check_rp[i]));// 断言页面属性无效
c01075f1:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01075f4:	8b 04 85 cc 40 1a c0 	mov    -0x3fe5bf34(,%eax,4),%eax
c01075fb:	83 c0 04             	add    $0x4,%eax
c01075fe:	c7 45 b4 01 00 00 00 	movl   $0x1,-0x4c(%ebp)
c0107605:	89 45 b0             	mov    %eax,-0x50(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0107608:	8b 45 b0             	mov    -0x50(%ebp),%eax
c010760b:	8b 55 b4             	mov    -0x4c(%ebp),%edx
c010760e:	0f a3 10             	bt     %edx,(%eax)
c0107611:	19 c0                	sbb    %eax,%eax
c0107613:	89 45 ac             	mov    %eax,-0x54(%ebp)
    return oldbit != 0;
c0107616:	83 7d ac 00          	cmpl   $0x0,-0x54(%ebp)
c010761a:	0f 95 c0             	setne  %al
c010761d:	0f b6 c0             	movzbl %al,%eax
c0107620:	85 c0                	test   %eax,%eax
c0107622:	74 24                	je     c0107648 <check_swap+0x306>
c0107624:	c7 44 24 0c 88 d7 10 	movl   $0xc010d788,0xc(%esp)
c010762b:	c0 
c010762c:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107633:	c0 
c0107634:	c7 44 24 04 de 00 00 	movl   $0xde,0x4(%esp)
c010763b:	00 
c010763c:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107643:	e8 f3 96 ff ff       	call   c0100d3b <__panic>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0107648:	ff 45 ec             	incl   -0x14(%ebp)
c010764b:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c010764f:	0f 8e 54 ff ff ff    	jle    c01075a9 <check_swap+0x267>
     }
     list_entry_t free_list_store = free_list;// 保存当前空闲列表
c0107655:	a1 84 3f 1a c0       	mov    0xc01a3f84,%eax
c010765a:	8b 15 88 3f 1a c0    	mov    0xc01a3f88,%edx
c0107660:	89 45 98             	mov    %eax,-0x68(%ebp)
c0107663:	89 55 9c             	mov    %edx,-0x64(%ebp)
c0107666:	c7 45 a4 84 3f 1a c0 	movl   $0xc01a3f84,-0x5c(%ebp)
    elm->prev = elm->next = elm;
c010766d:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c0107670:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c0107673:	89 50 04             	mov    %edx,0x4(%eax)
c0107676:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c0107679:	8b 50 04             	mov    0x4(%eax),%edx
c010767c:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c010767f:	89 10                	mov    %edx,(%eax)
}
c0107681:	90                   	nop
c0107682:	c7 45 a8 84 3f 1a c0 	movl   $0xc01a3f84,-0x58(%ebp)
    return list->next == list;
c0107689:	8b 45 a8             	mov    -0x58(%ebp),%eax
c010768c:	8b 40 04             	mov    0x4(%eax),%eax
c010768f:	39 45 a8             	cmp    %eax,-0x58(%ebp)
c0107692:	0f 94 c0             	sete   %al
c0107695:	0f b6 c0             	movzbl %al,%eax
     list_init(&free_list);// 初始化空闲列表
     assert(list_empty(&free_list));// 断言空闲列表为空
c0107698:	85 c0                	test   %eax,%eax
c010769a:	75 24                	jne    c01076c0 <check_swap+0x37e>
c010769c:	c7 44 24 0c a3 d7 10 	movl   $0xc010d7a3,0xc(%esp)
c01076a3:	c0 
c01076a4:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01076ab:	c0 
c01076ac:	c7 44 24 04 e2 00 00 	movl   $0xe2,0x4(%esp)
c01076b3:	00 
c01076b4:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01076bb:	e8 7b 96 ff ff       	call   c0100d3b <__panic>
     
     //assert(alloc_page() == NULL);
     
     unsigned int nr_free_store = nr_free;// 保存当前空闲页面数
c01076c0:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c01076c5:	89 45 d4             	mov    %eax,-0x2c(%ebp)
     nr_free = 0;// 将空闲页面数设为 0
c01076c8:	c7 05 8c 3f 1a c0 00 	movl   $0x0,0xc01a3f8c
c01076cf:	00 00 00 
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c01076d2:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c01076d9:	eb 1d                	jmp    c01076f8 <check_swap+0x3b6>
        free_pages(check_rp[i],1);// 释放页面
c01076db:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01076de:	8b 04 85 cc 40 1a c0 	mov    -0x3fe5bf34(,%eax,4),%eax
c01076e5:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01076ec:	00 
c01076ed:	89 04 24             	mov    %eax,(%esp)
c01076f0:	e8 f9 da ff ff       	call   c01051ee <free_pages>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c01076f5:	ff 45 ec             	incl   -0x14(%ebp)
c01076f8:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c01076fc:	7e dd                	jle    c01076db <check_swap+0x399>
     }
     assert(nr_free==CHECK_VALID_PHY_PAGE_NUM);// 断言释放的页面数正确
c01076fe:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c0107703:	83 f8 04             	cmp    $0x4,%eax
c0107706:	74 24                	je     c010772c <check_swap+0x3ea>
c0107708:	c7 44 24 0c bc d7 10 	movl   $0xc010d7bc,0xc(%esp)
c010770f:	c0 
c0107710:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107717:	c0 
c0107718:	c7 44 24 04 eb 00 00 	movl   $0xeb,0x4(%esp)
c010771f:	00 
c0107720:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107727:	e8 0f 96 ff ff       	call   c0100d3b <__panic>
     
     cprintf("set up init env for check_swap begin!\n");// 打印设置初始环境开始的信息
c010772c:	c7 04 24 e0 d7 10 c0 	movl   $0xc010d7e0,(%esp)
c0107733:	e8 40 8c ff ff       	call   c0100378 <cprintf>
     //setup initial vir_page<->phy_page environment for page relpacement algorithm 
     // 设置初始虚拟到物理页面环境，用于页面替换算法
     
     pgfault_num=0;// 初始化页面故障数
c0107738:	c7 05 10 41 1a c0 00 	movl   $0x0,0xc01a4110
c010773f:	00 00 00 
     
     check_content_set();// 设置检查内容
c0107742:	e8 26 fa ff ff       	call   c010716d <check_content_set>
     assert( nr_free == 0);  // 断言空闲页面数为 0       
c0107747:	a1 8c 3f 1a c0       	mov    0xc01a3f8c,%eax
c010774c:	85 c0                	test   %eax,%eax
c010774e:	74 24                	je     c0107774 <check_swap+0x432>
c0107750:	c7 44 24 0c 07 d8 10 	movl   $0xc010d807,0xc(%esp)
c0107757:	c0 
c0107758:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c010775f:	c0 
c0107760:	c7 44 24 04 f4 00 00 	movl   $0xf4,0x4(%esp)
c0107767:	00 
c0107768:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c010776f:	e8 c7 95 ff ff       	call   c0100d3b <__panic>
     for(i = 0; i<MAX_SEQ_NO ; i++) 
c0107774:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c010777b:	eb 25                	jmp    c01077a2 <check_swap+0x460>
         swap_out_seq_no[i]=swap_in_seq_no[i]=-1;// 初始化页面替换序列号
c010777d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107780:	c7 04 85 60 40 1a c0 	movl   $0xffffffff,-0x3fe5bfa0(,%eax,4)
c0107787:	ff ff ff ff 
c010778b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010778e:	8b 14 85 60 40 1a c0 	mov    -0x3fe5bfa0(,%eax,4),%edx
c0107795:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107798:	89 14 85 a0 40 1a c0 	mov    %edx,-0x3fe5bf60(,%eax,4)
     for(i = 0; i<MAX_SEQ_NO ; i++) 
c010779f:	ff 45 ec             	incl   -0x14(%ebp)
c01077a2:	83 7d ec 09          	cmpl   $0x9,-0x14(%ebp)
c01077a6:	7e d5                	jle    c010777d <check_swap+0x43b>
     
     for (i= 0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c01077a8:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c01077af:	e9 e8 00 00 00       	jmp    c010789c <check_swap+0x55a>
         check_ptep[i]=0;
c01077b4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01077b7:	c7 04 85 dc 40 1a c0 	movl   $0x0,-0x3fe5bf24(,%eax,4)
c01077be:	00 00 00 00 
         check_ptep[i] = get_pte(pgdir, (i+1)*0x1000, 0);// 获取页表项
c01077c2:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01077c5:	40                   	inc    %eax
c01077c6:	c1 e0 0c             	shl    $0xc,%eax
c01077c9:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01077d0:	00 
c01077d1:	89 44 24 04          	mov    %eax,0x4(%esp)
c01077d5:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01077d8:	89 04 24             	mov    %eax,(%esp)
c01077db:	e8 5c e0 ff ff       	call   c010583c <get_pte>
c01077e0:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01077e3:	89 04 95 dc 40 1a c0 	mov    %eax,-0x3fe5bf24(,%edx,4)
         //cprintf("i %d, check_ptep addr %x, value %x\n", i, check_ptep[i], *check_ptep[i]);
         assert(check_ptep[i] != NULL);// 断言获取页表项成功
c01077ea:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01077ed:	8b 04 85 dc 40 1a c0 	mov    -0x3fe5bf24(,%eax,4),%eax
c01077f4:	85 c0                	test   %eax,%eax
c01077f6:	75 24                	jne    c010781c <check_swap+0x4da>
c01077f8:	c7 44 24 0c 14 d8 10 	movl   $0xc010d814,0xc(%esp)
c01077ff:	c0 
c0107800:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107807:	c0 
c0107808:	c7 44 24 04 fc 00 00 	movl   $0xfc,0x4(%esp)
c010780f:	00 
c0107810:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107817:	e8 1f 95 ff ff       	call   c0100d3b <__panic>
         assert(pte2page(*check_ptep[i]) == check_rp[i]); // 断言页表项对应的页面正确
c010781c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010781f:	8b 04 85 dc 40 1a c0 	mov    -0x3fe5bf24(,%eax,4),%eax
c0107826:	8b 00                	mov    (%eax),%eax
c0107828:	89 04 24             	mov    %eax,(%esp)
c010782b:	e8 7d f5 ff ff       	call   c0106dad <pte2page>
c0107830:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0107833:	8b 14 95 cc 40 1a c0 	mov    -0x3fe5bf34(,%edx,4),%edx
c010783a:	39 d0                	cmp    %edx,%eax
c010783c:	74 24                	je     c0107862 <check_swap+0x520>
c010783e:	c7 44 24 0c 2c d8 10 	movl   $0xc010d82c,0xc(%esp)
c0107845:	c0 
c0107846:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c010784d:	c0 
c010784e:	c7 44 24 04 fd 00 00 	movl   $0xfd,0x4(%esp)
c0107855:	00 
c0107856:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c010785d:	e8 d9 94 ff ff       	call   c0100d3b <__panic>
         assert((*check_ptep[i] & PTE_P));  // 断言页表项有效        
c0107862:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107865:	8b 04 85 dc 40 1a c0 	mov    -0x3fe5bf24(,%eax,4),%eax
c010786c:	8b 00                	mov    (%eax),%eax
c010786e:	83 e0 01             	and    $0x1,%eax
c0107871:	85 c0                	test   %eax,%eax
c0107873:	75 24                	jne    c0107899 <check_swap+0x557>
c0107875:	c7 44 24 0c 54 d8 10 	movl   $0xc010d854,0xc(%esp)
c010787c:	c0 
c010787d:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c0107884:	c0 
c0107885:	c7 44 24 04 fe 00 00 	movl   $0xfe,0x4(%esp)
c010788c:	00 
c010788d:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c0107894:	e8 a2 94 ff ff       	call   c0100d3b <__panic>
     for (i= 0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0107899:	ff 45 ec             	incl   -0x14(%ebp)
c010789c:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c01078a0:	0f 8e 0e ff ff ff    	jle    c01077b4 <check_swap+0x472>
     }
     cprintf("set up init env for check_swap over!\n");// 打印设置初始环境完成的信息
c01078a6:	c7 04 24 70 d8 10 c0 	movl   $0xc010d870,(%esp)
c01078ad:	e8 c6 8a ff ff       	call   c0100378 <cprintf>
     // now access the virt pages to test  page relpacement algorithm 
     ret=check_content_access();
c01078b2:	e8 71 fa ff ff       	call   c0107328 <check_content_access>
c01078b7:	89 45 d0             	mov    %eax,-0x30(%ebp)
     assert(ret==0); // 断言访问检查成功
c01078ba:	83 7d d0 00          	cmpl   $0x0,-0x30(%ebp)
c01078be:	74 24                	je     c01078e4 <check_swap+0x5a2>
c01078c0:	c7 44 24 0c 96 d8 10 	movl   $0xc010d896,0xc(%esp)
c01078c7:	c0 
c01078c8:	c7 44 24 08 7e d5 10 	movl   $0xc010d57e,0x8(%esp)
c01078cf:	c0 
c01078d0:	c7 44 24 04 03 01 00 	movl   $0x103,0x4(%esp)
c01078d7:	00 
c01078d8:	c7 04 24 18 d5 10 c0 	movl   $0xc010d518,(%esp)
c01078df:	e8 57 94 ff ff       	call   c0100d3b <__panic>
     
     //restore kernel mem env
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c01078e4:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c01078eb:	eb 1d                	jmp    c010790a <check_swap+0x5c8>
         free_pages(check_rp[i],1);
c01078ed:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01078f0:	8b 04 85 cc 40 1a c0 	mov    -0x3fe5bf34(,%eax,4),%eax
c01078f7:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01078fe:	00 
c01078ff:	89 04 24             	mov    %eax,(%esp)
c0107902:	e8 e7 d8 ff ff       	call   c01051ee <free_pages>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0107907:	ff 45 ec             	incl   -0x14(%ebp)
c010790a:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c010790e:	7e dd                	jle    c01078ed <check_swap+0x5ab>
     } 

     //free_page(pte2page(*temp_ptep));
    free_page(pde2page(pgdir[0]));
c0107910:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107913:	8b 00                	mov    (%eax),%eax
c0107915:	89 04 24             	mov    %eax,(%esp)
c0107918:	e8 d0 f4 ff ff       	call   c0106ded <pde2page>
c010791d:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107924:	00 
c0107925:	89 04 24             	mov    %eax,(%esp)
c0107928:	e8 c1 d8 ff ff       	call   c01051ee <free_pages>
     pgdir[0] = 0;
c010792d:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107930:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
     mm->pgdir = NULL;
c0107936:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107939:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
     mm_destroy(mm);// 销毁内存管理结构
c0107940:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107943:	89 04 24             	mov    %eax,(%esp)
c0107946:	e8 d3 09 00 00       	call   c010831e <mm_destroy>
     check_mm_struct = NULL;
c010794b:	c7 05 0c 41 1a c0 00 	movl   $0x0,0xc01a410c
c0107952:	00 00 00 
     
     nr_free = nr_free_store;// 恢复空闲页面数
c0107955:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107958:	a3 8c 3f 1a c0       	mov    %eax,0xc01a3f8c
     free_list = free_list_store;// 恢复空闲列表
c010795d:	8b 45 98             	mov    -0x68(%ebp),%eax
c0107960:	8b 55 9c             	mov    -0x64(%ebp),%edx
c0107963:	a3 84 3f 1a c0       	mov    %eax,0xc01a3f84
c0107968:	89 15 88 3f 1a c0    	mov    %edx,0xc01a3f88

     
     le = &free_list;
c010796e:	c7 45 e8 84 3f 1a c0 	movl   $0xc01a3f84,-0x18(%ebp)
     while ((le = list_next(le)) != &free_list) {
c0107975:	eb 1c                	jmp    c0107993 <check_swap+0x651>
         struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构
c0107977:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010797a:	83 e8 0c             	sub    $0xc,%eax
c010797d:	89 45 cc             	mov    %eax,-0x34(%ebp)
         count --, total -= p->property;// 更新页面数量和属性总和
c0107980:	ff 4d f4             	decl   -0xc(%ebp)
c0107983:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0107986:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0107989:	8b 48 08             	mov    0x8(%eax),%ecx
c010798c:	89 d0                	mov    %edx,%eax
c010798e:	29 c8                	sub    %ecx,%eax
c0107990:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0107993:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107996:	89 45 a0             	mov    %eax,-0x60(%ebp)
    return listelm->next;
c0107999:	8b 45 a0             	mov    -0x60(%ebp),%eax
c010799c:	8b 40 04             	mov    0x4(%eax),%eax
     while ((le = list_next(le)) != &free_list) {
c010799f:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01079a2:	81 7d e8 84 3f 1a c0 	cmpl   $0xc01a3f84,-0x18(%ebp)
c01079a9:	75 cc                	jne    c0107977 <check_swap+0x635>
     }
     cprintf("count is %d, total is %d\n",count,total);// 打印恢复后的状态
c01079ab:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01079ae:	89 44 24 08          	mov    %eax,0x8(%esp)
c01079b2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01079b5:	89 44 24 04          	mov    %eax,0x4(%esp)
c01079b9:	c7 04 24 9d d8 10 c0 	movl   $0xc010d89d,(%esp)
c01079c0:	e8 b3 89 ff ff       	call   c0100378 <cprintf>
     //assert(count == 0);
     
     cprintf("check_swap() succeeded!\n");// 打印检查成功的信息
c01079c5:	c7 04 24 b7 d8 10 c0 	movl   $0xc010d8b7,(%esp)
c01079cc:	e8 a7 89 ff ff       	call   c0100378 <cprintf>
}
c01079d1:	90                   	nop
c01079d2:	89 ec                	mov    %ebp,%esp
c01079d4:	5d                   	pop    %ebp
c01079d5:	c3                   	ret    

c01079d6 <_fifo_init_mm>:
 * (2) _fifo_init_mm: init pra_list_head and let  mm->sm_priv point to the addr of pra_list_head.
 *              Now, From the memory control struct mm_struct, we can access FIFO PRA
 */
static int
_fifo_init_mm(struct mm_struct *mm)
{     
c01079d6:	55                   	push   %ebp
c01079d7:	89 e5                	mov    %esp,%ebp
c01079d9:	83 ec 10             	sub    $0x10,%esp
c01079dc:	c7 45 fc 04 41 1a c0 	movl   $0xc01a4104,-0x4(%ebp)
    elm->prev = elm->next = elm;
c01079e3:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01079e6:	8b 55 fc             	mov    -0x4(%ebp),%edx
c01079e9:	89 50 04             	mov    %edx,0x4(%eax)
c01079ec:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01079ef:	8b 50 04             	mov    0x4(%eax),%edx
c01079f2:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01079f5:	89 10                	mov    %edx,(%eax)
}
c01079f7:	90                   	nop
    //初始化一个链表头 pra_list_head
     list_init(&pra_list_head);
     //将 mm 结构中的 sm_priv 字段指向这个链表头
     mm->sm_priv = &pra_list_head;
c01079f8:	8b 45 08             	mov    0x8(%ebp),%eax
c01079fb:	c7 40 14 04 41 1a c0 	movl   $0xc01a4104,0x14(%eax)
     //cprintf(" mm->sm_priv %x in fifo_init_mm\n",mm->sm_priv);
     //返回 0 表示成功
     return 0;
c0107a02:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0107a07:	89 ec                	mov    %ebp,%esp
c0107a09:	5d                   	pop    %ebp
c0107a0a:	c3                   	ret    

c0107a0b <_fifo_map_swappable>:
/*
 * (3)_fifo_map_swappable: According FIFO PRA, we should link the most recent arrival page at the back of pra_list_head qeueue
 */
static int
_fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
{
c0107a0b:	55                   	push   %ebp
c0107a0c:	89 e5                	mov    %esp,%ebp
c0107a0e:	83 ec 48             	sub    $0x48,%esp
    //获取 mm_struct 结构中的 sm_priv 指针，
    //并将其转换为 list_entry_t 类型的链表头指针 head
    list_entry_t *head=(list_entry_t*) mm->sm_priv;
c0107a11:	8b 45 08             	mov    0x8(%ebp),%eax
c0107a14:	8b 40 14             	mov    0x14(%eax),%eax
c0107a17:	89 45 f4             	mov    %eax,-0xc(%ebp)
    list_entry_t *entry=&(page->pra_page_link);
c0107a1a:	8b 45 10             	mov    0x10(%ebp),%eax
c0107a1d:	83 c0 14             	add    $0x14,%eax
c0107a20:	89 45 f0             	mov    %eax,-0x10(%ebp)
 
    assert(entry != NULL && head != NULL);
c0107a23:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0107a27:	74 06                	je     c0107a2f <_fifo_map_swappable+0x24>
c0107a29:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107a2d:	75 24                	jne    c0107a53 <_fifo_map_swappable+0x48>
c0107a2f:	c7 44 24 0c d0 d8 10 	movl   $0xc010d8d0,0xc(%esp)
c0107a36:	c0 
c0107a37:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107a3e:	c0 
c0107a3f:	c7 44 24 04 37 00 00 	movl   $0x37,0x4(%esp)
c0107a46:	00 
c0107a47:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107a4e:	e8 e8 92 ff ff       	call   c0100d3b <__panic>
c0107a53:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107a56:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0107a59:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107a5c:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0107a5f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107a62:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0107a65:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107a68:	89 45 e0             	mov    %eax,-0x20(%ebp)
    __list_add(elm, listelm, listelm->next);
c0107a6b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107a6e:	8b 40 04             	mov    0x4(%eax),%eax
c0107a71:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0107a74:	89 55 dc             	mov    %edx,-0x24(%ebp)
c0107a77:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0107a7a:	89 55 d8             	mov    %edx,-0x28(%ebp)
c0107a7d:	89 45 d4             	mov    %eax,-0x2c(%ebp)
    prev->next = next->prev = elm;
c0107a80:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107a83:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0107a86:	89 10                	mov    %edx,(%eax)
c0107a88:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107a8b:	8b 10                	mov    (%eax),%edx
c0107a8d:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0107a90:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0107a93:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0107a96:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0107a99:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0107a9c:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0107a9f:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0107aa2:	89 10                	mov    %edx,(%eax)
}
c0107aa4:	90                   	nop
}
c0107aa5:	90                   	nop
}
c0107aa6:	90                   	nop
    //record the page access situlation
    /*LAB3 EXERCISE 2: YOUR CODE*/ 
    //(1)link the most recent arrival page at the back of the pra_list_head qeueue.
    //将最近到达的页面链接到 pra_list_head 队列的末尾
    list_add(head, entry);
    return 0;
c0107aa7:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0107aac:	89 ec                	mov    %ebp,%esp
c0107aae:	5d                   	pop    %ebp
c0107aaf:	c3                   	ret    

c0107ab0 <_fifo_swap_out_victim>:
 * 
 * @return 返回0表示成功，其他值表示失败。
 */
static int
_fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick)
{
c0107ab0:	55                   	push   %ebp
c0107ab1:	89 e5                	mov    %esp,%ebp
c0107ab3:	83 ec 38             	sub    $0x38,%esp
     list_entry_t *head=(list_entry_t*) mm->sm_priv;
c0107ab6:	8b 45 08             	mov    0x8(%ebp),%eax
c0107ab9:	8b 40 14             	mov    0x14(%eax),%eax
c0107abc:	89 45 f4             	mov    %eax,-0xc(%ebp)
         assert(head != NULL);
c0107abf:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107ac3:	75 24                	jne    c0107ae9 <_fifo_swap_out_victim+0x39>
c0107ac5:	c7 44 24 0c 17 d9 10 	movl   $0xc010d917,0xc(%esp)
c0107acc:	c0 
c0107acd:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107ad4:	c0 
c0107ad5:	c7 44 24 04 50 00 00 	movl   $0x50,0x4(%esp)
c0107adc:	00 
c0107add:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107ae4:	e8 52 92 ff ff       	call   c0100d3b <__panic>
     assert(in_tick==0);
c0107ae9:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0107aed:	74 24                	je     c0107b13 <_fifo_swap_out_victim+0x63>
c0107aef:	c7 44 24 0c 24 d9 10 	movl   $0xc010d924,0xc(%esp)
c0107af6:	c0 
c0107af7:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107afe:	c0 
c0107aff:	c7 44 24 04 51 00 00 	movl   $0x51,0x4(%esp)
c0107b06:	00 
c0107b07:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107b0e:	e8 28 92 ff ff       	call   c0100d3b <__panic>
     /* Select the victim */
     /*LAB3 EXERCISE 2: YOUR CODE*/ 
     //(1)  unlink the  earliest arrival page in front of pra_list_head qeueue
     //(2)  assign the value of *ptr_page to the addr of this page
     //head->prev 获取链表中最先到达的页面
     list_entry_t *le = head->prev;
c0107b13:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107b16:	8b 00                	mov    (%eax),%eax
c0107b18:	89 45 f0             	mov    %eax,-0x10(%ebp)
     assert(head!=le);
c0107b1b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107b1e:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c0107b21:	75 24                	jne    c0107b47 <_fifo_swap_out_victim+0x97>
c0107b23:	c7 44 24 0c 2f d9 10 	movl   $0xc010d92f,0xc(%esp)
c0107b2a:	c0 
c0107b2b:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107b32:	c0 
c0107b33:	c7 44 24 04 58 00 00 	movl   $0x58,0x4(%esp)
c0107b3a:	00 
c0107b3b:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107b42:	e8 f4 91 ff ff       	call   c0100d3b <__panic>
     struct Page *p = le2page(le, pra_page_link);
c0107b47:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107b4a:	83 e8 14             	sub    $0x14,%eax
c0107b4d:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0107b50:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107b53:	89 45 e8             	mov    %eax,-0x18(%ebp)
    __list_del(listelm->prev, listelm->next);
c0107b56:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107b59:	8b 40 04             	mov    0x4(%eax),%eax
c0107b5c:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0107b5f:	8b 12                	mov    (%edx),%edx
c0107b61:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c0107b64:	89 45 e0             	mov    %eax,-0x20(%ebp)
    prev->next = next;
c0107b67:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107b6a:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0107b6d:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0107b70:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107b73:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0107b76:	89 10                	mov    %edx,(%eax)
}
c0107b78:	90                   	nop
}
c0107b79:	90                   	nop
     //使用 list_del 函数将该页面从链表中移除。
     list_del(le);
     assert(p != NULL);
c0107b7a:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0107b7e:	75 24                	jne    c0107ba4 <_fifo_swap_out_victim+0xf4>
c0107b80:	c7 44 24 0c 38 d9 10 	movl   $0xc010d938,0xc(%esp)
c0107b87:	c0 
c0107b88:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107b8f:	c0 
c0107b90:	c7 44 24 04 5c 00 00 	movl   $0x5c,0x4(%esp)
c0107b97:	00 
c0107b98:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107b9f:	e8 97 91 ff ff       	call   c0100d3b <__panic>
     //将移除的页面指针赋值给 *ptr_page
     *ptr_page = p;
c0107ba4:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107ba7:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0107baa:	89 10                	mov    %edx,(%eax)
     
     return 0;
c0107bac:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0107bb1:	89 ec                	mov    %ebp,%esp
c0107bb3:	5d                   	pop    %ebp
c0107bb4:	c3                   	ret    

c0107bb5 <_fifo_check_swap>:
 * 
 * 返回值:
 * - 0: 表示所有检查均通过。
 */
static int
_fifo_check_swap(void) {
c0107bb5:	55                   	push   %ebp
c0107bb6:	89 e5                	mov    %esp,%ebp
c0107bb8:	83 ec 18             	sub    $0x18,%esp
    // 写入虚拟页 c 并检查页面故障数
    cprintf("write Virt Page c in fifo_check_swap\n");
c0107bbb:	c7 04 24 44 d9 10 c0 	movl   $0xc010d944,(%esp)
c0107bc2:	e8 b1 87 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x3000 = 0x0c;
c0107bc7:	b8 00 30 00 00       	mov    $0x3000,%eax
c0107bcc:	c6 00 0c             	movb   $0xc,(%eax)
    assert(pgfault_num==4);
c0107bcf:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107bd4:	83 f8 04             	cmp    $0x4,%eax
c0107bd7:	74 24                	je     c0107bfd <_fifo_check_swap+0x48>
c0107bd9:	c7 44 24 0c 6a d9 10 	movl   $0xc010d96a,0xc(%esp)
c0107be0:	c0 
c0107be1:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107be8:	c0 
c0107be9:	c7 44 24 04 70 00 00 	movl   $0x70,0x4(%esp)
c0107bf0:	00 
c0107bf1:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107bf8:	e8 3e 91 ff ff       	call   c0100d3b <__panic>

    // 写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c0107bfd:	c7 04 24 7c d9 10 c0 	movl   $0xc010d97c,(%esp)
c0107c04:	e8 6f 87 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x1000 = 0x0a;
c0107c09:	b8 00 10 00 00       	mov    $0x1000,%eax
c0107c0e:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==4);
c0107c11:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107c16:	83 f8 04             	cmp    $0x4,%eax
c0107c19:	74 24                	je     c0107c3f <_fifo_check_swap+0x8a>
c0107c1b:	c7 44 24 0c 6a d9 10 	movl   $0xc010d96a,0xc(%esp)
c0107c22:	c0 
c0107c23:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107c2a:	c0 
c0107c2b:	c7 44 24 04 75 00 00 	movl   $0x75,0x4(%esp)
c0107c32:	00 
c0107c33:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107c3a:	e8 fc 90 ff ff       	call   c0100d3b <__panic>

    // 写入虚拟页 d 并检查页面故障数
    cprintf("write Virt Page d in fifo_check_swap\n");
c0107c3f:	c7 04 24 a4 d9 10 c0 	movl   $0xc010d9a4,(%esp)
c0107c46:	e8 2d 87 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x4000 = 0x0d;
c0107c4b:	b8 00 40 00 00       	mov    $0x4000,%eax
c0107c50:	c6 00 0d             	movb   $0xd,(%eax)
    assert(pgfault_num==4);
c0107c53:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107c58:	83 f8 04             	cmp    $0x4,%eax
c0107c5b:	74 24                	je     c0107c81 <_fifo_check_swap+0xcc>
c0107c5d:	c7 44 24 0c 6a d9 10 	movl   $0xc010d96a,0xc(%esp)
c0107c64:	c0 
c0107c65:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107c6c:	c0 
c0107c6d:	c7 44 24 04 7a 00 00 	movl   $0x7a,0x4(%esp)
c0107c74:	00 
c0107c75:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107c7c:	e8 ba 90 ff ff       	call   c0100d3b <__panic>

    // 写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c0107c81:	c7 04 24 cc d9 10 c0 	movl   $0xc010d9cc,(%esp)
c0107c88:	e8 eb 86 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c0107c8d:	b8 00 20 00 00       	mov    $0x2000,%eax
c0107c92:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==4);
c0107c95:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107c9a:	83 f8 04             	cmp    $0x4,%eax
c0107c9d:	74 24                	je     c0107cc3 <_fifo_check_swap+0x10e>
c0107c9f:	c7 44 24 0c 6a d9 10 	movl   $0xc010d96a,0xc(%esp)
c0107ca6:	c0 
c0107ca7:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107cae:	c0 
c0107caf:	c7 44 24 04 7f 00 00 	movl   $0x7f,0x4(%esp)
c0107cb6:	00 
c0107cb7:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107cbe:	e8 78 90 ff ff       	call   c0100d3b <__panic>

    // 写入虚拟页 e 并检查页面故障数
    cprintf("write Virt Page e in fifo_check_swap\n");
c0107cc3:	c7 04 24 f4 d9 10 c0 	movl   $0xc010d9f4,(%esp)
c0107cca:	e8 a9 86 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x5000 = 0x0e;
c0107ccf:	b8 00 50 00 00       	mov    $0x5000,%eax
c0107cd4:	c6 00 0e             	movb   $0xe,(%eax)
    assert(pgfault_num==5);
c0107cd7:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107cdc:	83 f8 05             	cmp    $0x5,%eax
c0107cdf:	74 24                	je     c0107d05 <_fifo_check_swap+0x150>
c0107ce1:	c7 44 24 0c 1a da 10 	movl   $0xc010da1a,0xc(%esp)
c0107ce8:	c0 
c0107ce9:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107cf0:	c0 
c0107cf1:	c7 44 24 04 84 00 00 	movl   $0x84,0x4(%esp)
c0107cf8:	00 
c0107cf9:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107d00:	e8 36 90 ff ff       	call   c0100d3b <__panic>

    // 再次写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c0107d05:	c7 04 24 cc d9 10 c0 	movl   $0xc010d9cc,(%esp)
c0107d0c:	e8 67 86 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c0107d11:	b8 00 20 00 00       	mov    $0x2000,%eax
c0107d16:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==5);
c0107d19:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107d1e:	83 f8 05             	cmp    $0x5,%eax
c0107d21:	74 24                	je     c0107d47 <_fifo_check_swap+0x192>
c0107d23:	c7 44 24 0c 1a da 10 	movl   $0xc010da1a,0xc(%esp)
c0107d2a:	c0 
c0107d2b:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107d32:	c0 
c0107d33:	c7 44 24 04 89 00 00 	movl   $0x89,0x4(%esp)
c0107d3a:	00 
c0107d3b:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107d42:	e8 f4 8f ff ff       	call   c0100d3b <__panic>

    // 再次写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c0107d47:	c7 04 24 7c d9 10 c0 	movl   $0xc010d97c,(%esp)
c0107d4e:	e8 25 86 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x1000 = 0x0a;
c0107d53:	b8 00 10 00 00       	mov    $0x1000,%eax
c0107d58:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==6);
c0107d5b:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107d60:	83 f8 06             	cmp    $0x6,%eax
c0107d63:	74 24                	je     c0107d89 <_fifo_check_swap+0x1d4>
c0107d65:	c7 44 24 0c 29 da 10 	movl   $0xc010da29,0xc(%esp)
c0107d6c:	c0 
c0107d6d:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107d74:	c0 
c0107d75:	c7 44 24 04 8e 00 00 	movl   $0x8e,0x4(%esp)
c0107d7c:	00 
c0107d7d:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107d84:	e8 b2 8f ff ff       	call   c0100d3b <__panic>

    // 再次写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c0107d89:	c7 04 24 cc d9 10 c0 	movl   $0xc010d9cc,(%esp)
c0107d90:	e8 e3 85 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c0107d95:	b8 00 20 00 00       	mov    $0x2000,%eax
c0107d9a:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==7);
c0107d9d:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107da2:	83 f8 07             	cmp    $0x7,%eax
c0107da5:	74 24                	je     c0107dcb <_fifo_check_swap+0x216>
c0107da7:	c7 44 24 0c 38 da 10 	movl   $0xc010da38,0xc(%esp)
c0107dae:	c0 
c0107daf:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107db6:	c0 
c0107db7:	c7 44 24 04 93 00 00 	movl   $0x93,0x4(%esp)
c0107dbe:	00 
c0107dbf:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107dc6:	e8 70 8f ff ff       	call   c0100d3b <__panic>

    // 再次写入虚拟页 c 并检查页面故障数
    cprintf("write Virt Page c in fifo_check_swap\n");
c0107dcb:	c7 04 24 44 d9 10 c0 	movl   $0xc010d944,(%esp)
c0107dd2:	e8 a1 85 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x3000 = 0x0c;
c0107dd7:	b8 00 30 00 00       	mov    $0x3000,%eax
c0107ddc:	c6 00 0c             	movb   $0xc,(%eax)
    assert(pgfault_num==8);
c0107ddf:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107de4:	83 f8 08             	cmp    $0x8,%eax
c0107de7:	74 24                	je     c0107e0d <_fifo_check_swap+0x258>
c0107de9:	c7 44 24 0c 47 da 10 	movl   $0xc010da47,0xc(%esp)
c0107df0:	c0 
c0107df1:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107df8:	c0 
c0107df9:	c7 44 24 04 98 00 00 	movl   $0x98,0x4(%esp)
c0107e00:	00 
c0107e01:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107e08:	e8 2e 8f ff ff       	call   c0100d3b <__panic>

    // 再次写入虚拟页 d 并检查页面故障数
    cprintf("write Virt Page d in fifo_check_swap\n");
c0107e0d:	c7 04 24 a4 d9 10 c0 	movl   $0xc010d9a4,(%esp)
c0107e14:	e8 5f 85 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x4000 = 0x0d;
c0107e19:	b8 00 40 00 00       	mov    $0x4000,%eax
c0107e1e:	c6 00 0d             	movb   $0xd,(%eax)
    assert(pgfault_num==9);
c0107e21:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107e26:	83 f8 09             	cmp    $0x9,%eax
c0107e29:	74 24                	je     c0107e4f <_fifo_check_swap+0x29a>
c0107e2b:	c7 44 24 0c 56 da 10 	movl   $0xc010da56,0xc(%esp)
c0107e32:	c0 
c0107e33:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107e3a:	c0 
c0107e3b:	c7 44 24 04 9d 00 00 	movl   $0x9d,0x4(%esp)
c0107e42:	00 
c0107e43:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107e4a:	e8 ec 8e ff ff       	call   c0100d3b <__panic>

     // 再次写入虚拟页 e 并检查页面故障数
    cprintf("write Virt Page e in fifo_check_swap\n");
c0107e4f:	c7 04 24 f4 d9 10 c0 	movl   $0xc010d9f4,(%esp)
c0107e56:	e8 1d 85 ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x5000 = 0x0e;
c0107e5b:	b8 00 50 00 00       	mov    $0x5000,%eax
c0107e60:	c6 00 0e             	movb   $0xe,(%eax)
    assert(pgfault_num==10);
c0107e63:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107e68:	83 f8 0a             	cmp    $0xa,%eax
c0107e6b:	74 24                	je     c0107e91 <_fifo_check_swap+0x2dc>
c0107e6d:	c7 44 24 0c 65 da 10 	movl   $0xc010da65,0xc(%esp)
c0107e74:	c0 
c0107e75:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107e7c:	c0 
c0107e7d:	c7 44 24 04 a2 00 00 	movl   $0xa2,0x4(%esp)
c0107e84:	00 
c0107e85:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107e8c:	e8 aa 8e ff ff       	call   c0100d3b <__panic>

    // 再次写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c0107e91:	c7 04 24 7c d9 10 c0 	movl   $0xc010d97c,(%esp)
c0107e98:	e8 db 84 ff ff       	call   c0100378 <cprintf>
    assert(*(unsigned char *)0x1000 == 0x0a);
c0107e9d:	b8 00 10 00 00       	mov    $0x1000,%eax
c0107ea2:	0f b6 00             	movzbl (%eax),%eax
c0107ea5:	3c 0a                	cmp    $0xa,%al
c0107ea7:	74 24                	je     c0107ecd <_fifo_check_swap+0x318>
c0107ea9:	c7 44 24 0c 78 da 10 	movl   $0xc010da78,0xc(%esp)
c0107eb0:	c0 
c0107eb1:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107eb8:	c0 
c0107eb9:	c7 44 24 04 a6 00 00 	movl   $0xa6,0x4(%esp)
c0107ec0:	00 
c0107ec1:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107ec8:	e8 6e 8e ff ff       	call   c0100d3b <__panic>
    *(unsigned char *)0x1000 = 0x0a;
c0107ecd:	b8 00 10 00 00       	mov    $0x1000,%eax
c0107ed2:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==11);
c0107ed5:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0107eda:	83 f8 0b             	cmp    $0xb,%eax
c0107edd:	74 24                	je     c0107f03 <_fifo_check_swap+0x34e>
c0107edf:	c7 44 24 0c 99 da 10 	movl   $0xc010da99,0xc(%esp)
c0107ee6:	c0 
c0107ee7:	c7 44 24 08 ee d8 10 	movl   $0xc010d8ee,0x8(%esp)
c0107eee:	c0 
c0107eef:	c7 44 24 04 a8 00 00 	movl   $0xa8,0x4(%esp)
c0107ef6:	00 
c0107ef7:	c7 04 24 03 d9 10 c0 	movl   $0xc010d903,(%esp)
c0107efe:	e8 38 8e ff ff       	call   c0100d3b <__panic>
    return 0;
c0107f03:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0107f08:	89 ec                	mov    %ebp,%esp
c0107f0a:	5d                   	pop    %ebp
c0107f0b:	c3                   	ret    

c0107f0c <_fifo_init>:


static int
_fifo_init(void)
{
c0107f0c:	55                   	push   %ebp
c0107f0d:	89 e5                	mov    %esp,%ebp
    return 0;
c0107f0f:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0107f14:	5d                   	pop    %ebp
c0107f15:	c3                   	ret    

c0107f16 <_fifo_set_unswappable>:

static int
_fifo_set_unswappable(struct mm_struct *mm, uintptr_t addr)
{
c0107f16:	55                   	push   %ebp
c0107f17:	89 e5                	mov    %esp,%ebp
    return 0;
c0107f19:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0107f1e:	5d                   	pop    %ebp
c0107f1f:	c3                   	ret    

c0107f20 <_fifo_tick_event>:

static int
_fifo_tick_event(struct mm_struct *mm)
{ return 0; }
c0107f20:	55                   	push   %ebp
c0107f21:	89 e5                	mov    %esp,%ebp
c0107f23:	b8 00 00 00 00       	mov    $0x0,%eax
c0107f28:	5d                   	pop    %ebp
c0107f29:	c3                   	ret    

c0107f2a <lock_init>:
#define local_intr_restore(x)   __intr_restore(x);

typedef volatile bool lock_t;

static inline void
lock_init(lock_t *lock) {
c0107f2a:	55                   	push   %ebp
c0107f2b:	89 e5                	mov    %esp,%ebp
    *lock = 0;
c0107f2d:	8b 45 08             	mov    0x8(%ebp),%eax
c0107f30:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
}
c0107f36:	90                   	nop
c0107f37:	5d                   	pop    %ebp
c0107f38:	c3                   	ret    

c0107f39 <mm_count>:
bool user_mem_check(struct mm_struct *mm, uintptr_t start, size_t len, bool write);
bool copy_from_user(struct mm_struct *mm, void *dst, const void *src, size_t len, bool writable);
bool copy_to_user(struct mm_struct *mm, void *dst, const void *src, size_t len);

static inline int
mm_count(struct mm_struct *mm) {
c0107f39:	55                   	push   %ebp
c0107f3a:	89 e5                	mov    %esp,%ebp
    return mm->mm_count;
c0107f3c:	8b 45 08             	mov    0x8(%ebp),%eax
c0107f3f:	8b 40 18             	mov    0x18(%eax),%eax
}
c0107f42:	5d                   	pop    %ebp
c0107f43:	c3                   	ret    

c0107f44 <set_mm_count>:

static inline void
set_mm_count(struct mm_struct *mm, int val) {
c0107f44:	55                   	push   %ebp
c0107f45:	89 e5                	mov    %esp,%ebp
    mm->mm_count = val;
c0107f47:	8b 45 08             	mov    0x8(%ebp),%eax
c0107f4a:	8b 55 0c             	mov    0xc(%ebp),%edx
c0107f4d:	89 50 18             	mov    %edx,0x18(%eax)
}
c0107f50:	90                   	nop
c0107f51:	5d                   	pop    %ebp
c0107f52:	c3                   	ret    

c0107f53 <pa2page>:
pa2page(uintptr_t pa) {
c0107f53:	55                   	push   %ebp
c0107f54:	89 e5                	mov    %esp,%ebp
c0107f56:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c0107f59:	8b 45 08             	mov    0x8(%ebp),%eax
c0107f5c:	c1 e8 0c             	shr    $0xc,%eax
c0107f5f:	89 c2                	mov    %eax,%edx
c0107f61:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0107f66:	39 c2                	cmp    %eax,%edx
c0107f68:	72 1c                	jb     c0107f86 <pa2page+0x33>
        panic("pa2page called with invalid pa");
c0107f6a:	c7 44 24 08 bc da 10 	movl   $0xc010dabc,0x8(%esp)
c0107f71:	c0 
c0107f72:	c7 44 24 04 5e 00 00 	movl   $0x5e,0x4(%esp)
c0107f79:	00 
c0107f7a:	c7 04 24 db da 10 c0 	movl   $0xc010dadb,(%esp)
c0107f81:	e8 b5 8d ff ff       	call   c0100d3b <__panic>
    return &pages[PPN(pa)];
c0107f86:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c0107f8c:	8b 45 08             	mov    0x8(%ebp),%eax
c0107f8f:	c1 e8 0c             	shr    $0xc,%eax
c0107f92:	c1 e0 05             	shl    $0x5,%eax
c0107f95:	01 d0                	add    %edx,%eax
}
c0107f97:	89 ec                	mov    %ebp,%esp
c0107f99:	5d                   	pop    %ebp
c0107f9a:	c3                   	ret    

c0107f9b <pde2page>:
pde2page(pde_t pde) {
c0107f9b:	55                   	push   %ebp
c0107f9c:	89 e5                	mov    %esp,%ebp
c0107f9e:	83 ec 18             	sub    $0x18,%esp
    return pa2page(PDE_ADDR(pde));
c0107fa1:	8b 45 08             	mov    0x8(%ebp),%eax
c0107fa4:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0107fa9:	89 04 24             	mov    %eax,(%esp)
c0107fac:	e8 a2 ff ff ff       	call   c0107f53 <pa2page>
}
c0107fb1:	89 ec                	mov    %ebp,%esp
c0107fb3:	5d                   	pop    %ebp
c0107fb4:	c3                   	ret    

c0107fb5 <mm_create>:
 * 它包括内存映射列表、页目录、映射缓存等重要信息
 * 
 * @return 分配并初始化后的`mm_struct`结构体指针，如果分配失败则返回NULL
 */
struct mm_struct *
mm_create(void) {
c0107fb5:	55                   	push   %ebp
c0107fb6:	89 e5                	mov    %esp,%ebp
c0107fb8:	83 ec 28             	sub    $0x28,%esp
    // 分配一个mm_struct结构体的空间
    struct mm_struct *mm = kmalloc(sizeof(struct mm_struct));
c0107fbb:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c0107fc2:	e8 29 cd ff ff       	call   c0104cf0 <kmalloc>
c0107fc7:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查是否成功分配了内存
    if (mm != NULL) {
c0107fca:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107fce:	74 7a                	je     c010804a <mm_create+0x95>
        // 初始化内存映射列表
        list_init(&(mm->mmap_list));
c0107fd0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107fd3:	89 45 f0             	mov    %eax,-0x10(%ebp)
    elm->prev = elm->next = elm;
c0107fd6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107fd9:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0107fdc:	89 50 04             	mov    %edx,0x4(%eax)
c0107fdf:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107fe2:	8b 50 04             	mov    0x4(%eax),%edx
c0107fe5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107fe8:	89 10                	mov    %edx,(%eax)
}
c0107fea:	90                   	nop
        // 设置映射缓存为NULL，表示尚未缓存任何映射
        mm->mmap_cache = NULL;
c0107feb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107fee:	c7 40 08 00 00 00 00 	movl   $0x0,0x8(%eax)
        // 设置页目录为NULL，表示尚未分配页目录
        mm->pgdir = NULL;
c0107ff5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107ff8:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
        // 初始化映射计数为0，表示尚未创建任何内存映射
        mm->map_count = 0;
c0107fff:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108002:	c7 40 10 00 00 00 00 	movl   $0x0,0x10(%eax)
        // 如果交换空间初始化成功，则为当前内存管理结构体进行交换空间初始化
        if (swap_init_ok) swap_init_mm(mm);
c0108009:	a1 44 40 1a c0       	mov    0xc01a4044,%eax
c010800e:	85 c0                	test   %eax,%eax
c0108010:	74 0d                	je     c010801f <mm_create+0x6a>
c0108012:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108015:	89 04 24             	mov    %eax,(%esp)
c0108018:	e8 7c ee ff ff       	call   c0106e99 <swap_init_mm>
c010801d:	eb 0a                	jmp    c0108029 <mm_create+0x74>
        else mm->sm_priv = NULL;
c010801f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108022:	c7 40 14 00 00 00 00 	movl   $0x0,0x14(%eax)
        //设置引用计数和锁：
        set_mm_count(mm, 0);
c0108029:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0108030:	00 
c0108031:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108034:	89 04 24             	mov    %eax,(%esp)
c0108037:	e8 08 ff ff ff       	call   c0107f44 <set_mm_count>
        lock_init(&(mm->mm_lock));
c010803c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010803f:	83 c0 1c             	add    $0x1c,%eax
c0108042:	89 04 24             	mov    %eax,(%esp)
c0108045:	e8 e0 fe ff ff       	call   c0107f2a <lock_init>
    }    
    return mm;
c010804a:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010804d:	89 ec                	mov    %ebp,%esp
c010804f:	5d                   	pop    %ebp
c0108050:	c3                   	ret    

c0108051 <vma_create>:
 * @param vm_flags 虚拟内存区域的标志，表示内存区域的权限和特性。
 * 
 * @return 返回指向新创建的vma_struct结构体的指针，如果内存分配失败，则返回NULL。
 */
struct vma_struct *
vma_create(uintptr_t vm_start, uintptr_t vm_end, uint32_t vm_flags) {
c0108051:	55                   	push   %ebp
c0108052:	89 e5                	mov    %esp,%ebp
c0108054:	83 ec 28             	sub    $0x28,%esp
    // 分配vma_struct结构体所需的内存空间
    struct vma_struct *vma = kmalloc(sizeof(struct vma_struct));
c0108057:	c7 04 24 18 00 00 00 	movl   $0x18,(%esp)
c010805e:	e8 8d cc ff ff       	call   c0104cf0 <kmalloc>
c0108063:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查内存是否成功分配
    if (vma != NULL) {
c0108066:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010806a:	74 1b                	je     c0108087 <vma_create+0x36>
        // 初始化vma_struct的成员变量
        vma->vm_start = vm_start;
c010806c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010806f:	8b 55 08             	mov    0x8(%ebp),%edx
c0108072:	89 50 04             	mov    %edx,0x4(%eax)
        vma->vm_end = vm_end;
c0108075:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108078:	8b 55 0c             	mov    0xc(%ebp),%edx
c010807b:	89 50 08             	mov    %edx,0x8(%eax)
        vma->vm_flags = vm_flags;
c010807e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108081:	8b 55 10             	mov    0x10(%ebp),%edx
c0108084:	89 50 0c             	mov    %edx,0xc(%eax)
    }
    // 返回指向新创建的vma_struct结构体的指针，或在内存分配失败时返回NULL
    return vma;
c0108087:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010808a:	89 ec                	mov    %ebp,%esp
c010808c:	5d                   	pop    %ebp
c010808d:	c3                   	ret    

c010808e <find_vma>:
 * 此函数首先检查mmap_cache是否包含所需的VMA，以加速查找过程
 * 如果mmap_cache未命中，则遍历VMA列表，直到找到包含给定地址的VMA或确定不存在这样的VMA
 * 如果找到了合适的VMA，它将更新mmap_cache以供后续查找使用
 */
struct vma_struct *
find_vma(struct mm_struct *mm, uintptr_t addr) {
c010808e:	55                   	push   %ebp
c010808f:	89 e5                	mov    %esp,%ebp
c0108091:	83 ec 20             	sub    $0x20,%esp
    struct vma_struct *vma = NULL;// 初始化VMA指针为NULL
c0108094:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    if (mm != NULL) {// 检查传入的内存描述符是否有效
c010809b:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c010809f:	0f 84 95 00 00 00    	je     c010813a <find_vma+0xac>
        // 检查mmap_cache是否包含所需的VMA
        vma = mm->mmap_cache;
c01080a5:	8b 45 08             	mov    0x8(%ebp),%eax
c01080a8:	8b 40 08             	mov    0x8(%eax),%eax
c01080ab:	89 45 fc             	mov    %eax,-0x4(%ebp)
        if (!(vma != NULL && vma->vm_start <= addr && vma->vm_end > addr)) {
c01080ae:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c01080b2:	74 16                	je     c01080ca <find_vma+0x3c>
c01080b4:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01080b7:	8b 40 04             	mov    0x4(%eax),%eax
c01080ba:	39 45 0c             	cmp    %eax,0xc(%ebp)
c01080bd:	72 0b                	jb     c01080ca <find_vma+0x3c>
c01080bf:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01080c2:	8b 40 08             	mov    0x8(%eax),%eax
c01080c5:	39 45 0c             	cmp    %eax,0xc(%ebp)
c01080c8:	72 61                	jb     c010812b <find_vma+0x9d>
                // 如果mmap_cache未命中，则开始遍历VMA列表
                bool found = 0;// 初始化找到标志为0
c01080ca:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%ebp)
                // 获取VMA列表的头指针
                list_entry_t *list = &(mm->mmap_list), *le = list;
c01080d1:	8b 45 08             	mov    0x8(%ebp),%eax
c01080d4:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01080d7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01080da:	89 45 f4             	mov    %eax,-0xc(%ebp)
                while ((le = list_next(le)) != list) { // 遍历VMA列表
c01080dd:	eb 28                	jmp    c0108107 <find_vma+0x79>
                    vma = le2vma(le, list_link);// 将链表项转换为VMA结构
c01080df:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01080e2:	83 e8 10             	sub    $0x10,%eax
c01080e5:	89 45 fc             	mov    %eax,-0x4(%ebp)
                    // 检查当前VMA是否包含给定地址
                    if (vma->vm_start<=addr && addr < vma->vm_end) {
c01080e8:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01080eb:	8b 40 04             	mov    0x4(%eax),%eax
c01080ee:	39 45 0c             	cmp    %eax,0xc(%ebp)
c01080f1:	72 14                	jb     c0108107 <find_vma+0x79>
c01080f3:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01080f6:	8b 40 08             	mov    0x8(%eax),%eax
c01080f9:	39 45 0c             	cmp    %eax,0xc(%ebp)
c01080fc:	73 09                	jae    c0108107 <find_vma+0x79>
                        found = 1;// 找到合适的VMA
c01080fe:	c7 45 f8 01 00 00 00 	movl   $0x1,-0x8(%ebp)
                        break;// 结束循环
c0108105:	eb 17                	jmp    c010811e <find_vma+0x90>
c0108107:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010810a:	89 45 ec             	mov    %eax,-0x14(%ebp)
    return listelm->next;
c010810d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108110:	8b 40 04             	mov    0x4(%eax),%eax
                while ((le = list_next(le)) != list) { // 遍历VMA列表
c0108113:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108116:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108119:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c010811c:	75 c1                	jne    c01080df <find_vma+0x51>
                    }
                }
                if (!found) {// 如果未找到合适的VMA
c010811e:	83 7d f8 00          	cmpl   $0x0,-0x8(%ebp)
c0108122:	75 07                	jne    c010812b <find_vma+0x9d>
                    vma = NULL;// 将VMA指针设置为NULL
c0108124:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
                }
        }
        // 如果找到了合适的VMA，更新mmap_cache
        if (vma != NULL) {
c010812b:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c010812f:	74 09                	je     c010813a <find_vma+0xac>
            mm->mmap_cache = vma;// 更新mmap_cache以加速后续查找
c0108131:	8b 45 08             	mov    0x8(%ebp),%eax
c0108134:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0108137:	89 50 08             	mov    %edx,0x8(%eax)
        }
    }
    return vma;
c010813a:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c010813d:	89 ec                	mov    %ebp,%esp
c010813f:	5d                   	pop    %ebp
c0108140:	c3                   	ret    

c0108141 <check_vma_overlap>:
 * 
 * @param prev 指向前一个虚拟内存区域（VMA）的结构体指针
 * @param next 指向后一个虚拟内存区域（VMA）的结构体指针
 */
static inline void
check_vma_overlap(struct vma_struct *prev, struct vma_struct *next) {
c0108141:	55                   	push   %ebp
c0108142:	89 e5                	mov    %esp,%ebp
c0108144:	83 ec 18             	sub    $0x18,%esp
    assert(prev->vm_start < prev->vm_end);// 确保前一个VMA的地址范围是有效的
c0108147:	8b 45 08             	mov    0x8(%ebp),%eax
c010814a:	8b 50 04             	mov    0x4(%eax),%edx
c010814d:	8b 45 08             	mov    0x8(%ebp),%eax
c0108150:	8b 40 08             	mov    0x8(%eax),%eax
c0108153:	39 c2                	cmp    %eax,%edx
c0108155:	72 24                	jb     c010817b <check_vma_overlap+0x3a>
c0108157:	c7 44 24 0c e9 da 10 	movl   $0xc010dae9,0xc(%esp)
c010815e:	c0 
c010815f:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108166:	c0 
c0108167:	c7 44 24 04 a2 00 00 	movl   $0xa2,0x4(%esp)
c010816e:	00 
c010816f:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108176:	e8 c0 8b ff ff       	call   c0100d3b <__panic>
    assert(prev->vm_end <= next->vm_start);// 确保两个VMA之间没有重叠
c010817b:	8b 45 08             	mov    0x8(%ebp),%eax
c010817e:	8b 50 08             	mov    0x8(%eax),%edx
c0108181:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108184:	8b 40 04             	mov    0x4(%eax),%eax
c0108187:	39 c2                	cmp    %eax,%edx
c0108189:	76 24                	jbe    c01081af <check_vma_overlap+0x6e>
c010818b:	c7 44 24 0c 2c db 10 	movl   $0xc010db2c,0xc(%esp)
c0108192:	c0 
c0108193:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c010819a:	c0 
c010819b:	c7 44 24 04 a3 00 00 	movl   $0xa3,0x4(%esp)
c01081a2:	00 
c01081a3:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c01081aa:	e8 8c 8b ff ff       	call   c0100d3b <__panic>
    assert(next->vm_start < next->vm_end);// 确保后一个VMA的地址范围是有效的
c01081af:	8b 45 0c             	mov    0xc(%ebp),%eax
c01081b2:	8b 50 04             	mov    0x4(%eax),%edx
c01081b5:	8b 45 0c             	mov    0xc(%ebp),%eax
c01081b8:	8b 40 08             	mov    0x8(%eax),%eax
c01081bb:	39 c2                	cmp    %eax,%edx
c01081bd:	72 24                	jb     c01081e3 <check_vma_overlap+0xa2>
c01081bf:	c7 44 24 0c 4b db 10 	movl   $0xc010db4b,0xc(%esp)
c01081c6:	c0 
c01081c7:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c01081ce:	c0 
c01081cf:	c7 44 24 04 a4 00 00 	movl   $0xa4,0x4(%esp)
c01081d6:	00 
c01081d7:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c01081de:	e8 58 8b ff ff       	call   c0100d3b <__panic>
}
c01081e3:	90                   	nop
c01081e4:	89 ec                	mov    %ebp,%esp
c01081e6:	5d                   	pop    %ebp
c01081e7:	c3                   	ret    

c01081e8 <insert_vma_struct>:
 *
 * @param mm 指向内存描述符结构 `struct mm_struct` 的指针，表示一个进程的内存空间。
 * @param vma 指向要插入的VMA结构 `struct vma_struct` 的指针，描述一个内存区域。
 */
void
insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) {
c01081e8:	55                   	push   %ebp
c01081e9:	89 e5                	mov    %esp,%ebp
c01081eb:	83 ec 48             	sub    $0x48,%esp
    // 断言VMA结构的起始地址小于结束地址，确保VMA结构的有效性。
    assert(vma->vm_start < vma->vm_end);
c01081ee:	8b 45 0c             	mov    0xc(%ebp),%eax
c01081f1:	8b 50 04             	mov    0x4(%eax),%edx
c01081f4:	8b 45 0c             	mov    0xc(%ebp),%eax
c01081f7:	8b 40 08             	mov    0x8(%eax),%eax
c01081fa:	39 c2                	cmp    %eax,%edx
c01081fc:	72 24                	jb     c0108222 <insert_vma_struct+0x3a>
c01081fe:	c7 44 24 0c 69 db 10 	movl   $0xc010db69,0xc(%esp)
c0108205:	c0 
c0108206:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c010820d:	c0 
c010820e:	c7 44 24 04 b5 00 00 	movl   $0xb5,0x4(%esp)
c0108215:	00 
c0108216:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c010821d:	e8 19 8b ff ff       	call   c0100d3b <__panic>
    // 指向内存描述符中的VMA链表。
    list_entry_t *list = &(mm->mmap_list);
c0108222:	8b 45 08             	mov    0x8(%ebp),%eax
c0108225:	89 45 ec             	mov    %eax,-0x14(%ebp)
     // 遍历链表以找到新VMA结构的正确插入位置。
    list_entry_t *le_prev = list, *le_next;
c0108228:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010822b:	89 45 f4             	mov    %eax,-0xc(%ebp)

        list_entry_t *le = list;
c010822e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108231:	89 45 f0             	mov    %eax,-0x10(%ebp)
        // 遍历链表以找到新VMA结构的正确插入位置
        while ((le = list_next(le)) != list) {
c0108234:	eb 1f                	jmp    c0108255 <insert_vma_struct+0x6d>
            struct vma_struct *mmap_prev = le2vma(le, list_link);
c0108236:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108239:	83 e8 10             	sub    $0x10,%eax
c010823c:	89 45 e8             	mov    %eax,-0x18(%ebp)
            // 如果当前VMA的起始地址大于新VMA的起始地址，则跳出循环
            if (mmap_prev->vm_start > vma->vm_start) {
c010823f:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108242:	8b 50 04             	mov    0x4(%eax),%edx
c0108245:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108248:	8b 40 04             	mov    0x4(%eax),%eax
c010824b:	39 c2                	cmp    %eax,%edx
c010824d:	77 1f                	ja     c010826e <insert_vma_struct+0x86>
                break;
            }
            le_prev = le;
c010824f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108252:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108255:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108258:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010825b:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010825e:	8b 40 04             	mov    0x4(%eax),%eax
        while ((le = list_next(le)) != list) {
c0108261:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108264:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108267:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c010826a:	75 ca                	jne    c0108236 <insert_vma_struct+0x4e>
c010826c:	eb 01                	jmp    c010826f <insert_vma_struct+0x87>
                break;
c010826e:	90                   	nop
c010826f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108272:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0108275:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108278:	8b 40 04             	mov    0x4(%eax),%eax
        }
    // 获取下一个链表项
    le_next = list_next(le_prev);
c010827b:	89 45 e4             	mov    %eax,-0x1c(%ebp)

    /* check overlap */
    // 检查前一个VMA结构是否与新VMA结构重叠
    if (le_prev != list) {
c010827e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108281:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0108284:	74 15                	je     c010829b <insert_vma_struct+0xb3>
        check_vma_overlap(le2vma(le_prev, list_link), vma);
c0108286:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108289:	8d 50 f0             	lea    -0x10(%eax),%edx
c010828c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010828f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108293:	89 14 24             	mov    %edx,(%esp)
c0108296:	e8 a6 fe ff ff       	call   c0108141 <check_vma_overlap>
    }
    // 检查下一个VMA结构是否与新VMA结构重叠
    if (le_next != list) {
c010829b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010829e:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c01082a1:	74 15                	je     c01082b8 <insert_vma_struct+0xd0>
        check_vma_overlap(vma, le2vma(le_next, list_link));
c01082a3:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01082a6:	83 e8 10             	sub    $0x10,%eax
c01082a9:	89 44 24 04          	mov    %eax,0x4(%esp)
c01082ad:	8b 45 0c             	mov    0xc(%ebp),%eax
c01082b0:	89 04 24             	mov    %eax,(%esp)
c01082b3:	e8 89 fe ff ff       	call   c0108141 <check_vma_overlap>
    }
    // 设置VMA结构所属的内存描述符
    vma->vm_mm = mm;
c01082b8:	8b 45 0c             	mov    0xc(%ebp),%eax
c01082bb:	8b 55 08             	mov    0x8(%ebp),%edx
c01082be:	89 10                	mov    %edx,(%eax)
    // 将新VMA结构插入链表
    list_add_after(le_prev, &(vma->list_link));
c01082c0:	8b 45 0c             	mov    0xc(%ebp),%eax
c01082c3:	8d 50 10             	lea    0x10(%eax),%edx
c01082c6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01082c9:	89 45 d8             	mov    %eax,-0x28(%ebp)
c01082cc:	89 55 d4             	mov    %edx,-0x2c(%ebp)
    __list_add(elm, listelm, listelm->next);
c01082cf:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01082d2:	8b 40 04             	mov    0x4(%eax),%eax
c01082d5:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01082d8:	89 55 d0             	mov    %edx,-0x30(%ebp)
c01082db:	8b 55 d8             	mov    -0x28(%ebp),%edx
c01082de:	89 55 cc             	mov    %edx,-0x34(%ebp)
c01082e1:	89 45 c8             	mov    %eax,-0x38(%ebp)
    prev->next = next->prev = elm;
c01082e4:	8b 45 c8             	mov    -0x38(%ebp),%eax
c01082e7:	8b 55 d0             	mov    -0x30(%ebp),%edx
c01082ea:	89 10                	mov    %edx,(%eax)
c01082ec:	8b 45 c8             	mov    -0x38(%ebp),%eax
c01082ef:	8b 10                	mov    (%eax),%edx
c01082f1:	8b 45 cc             	mov    -0x34(%ebp),%eax
c01082f4:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c01082f7:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01082fa:	8b 55 c8             	mov    -0x38(%ebp),%edx
c01082fd:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0108300:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0108303:	8b 55 cc             	mov    -0x34(%ebp),%edx
c0108306:	89 10                	mov    %edx,(%eax)
}
c0108308:	90                   	nop
}
c0108309:	90                   	nop
    // 增加内存描述符中的映射计数
    mm->map_count ++;
c010830a:	8b 45 08             	mov    0x8(%ebp),%eax
c010830d:	8b 40 10             	mov    0x10(%eax),%eax
c0108310:	8d 50 01             	lea    0x1(%eax),%edx
c0108313:	8b 45 08             	mov    0x8(%ebp),%eax
c0108316:	89 50 10             	mov    %edx,0x10(%eax)
}
c0108319:	90                   	nop
c010831a:	89 ec                	mov    %ebp,%esp
c010831c:	5d                   	pop    %ebp
c010831d:	c3                   	ret    

c010831e <mm_destroy>:
 * 此函数遍历并销毁与内存管理结构（mm_struct）关联的所有虚拟内存区域（VMA），
 * 然后释放内存管理结构本身所占用的内存。这样做是为了确保在销毁内存管理结构之前，
 * 所有相关的资源都被正确地释放。
 */
void
mm_destroy(struct mm_struct *mm) {
c010831e:	55                   	push   %ebp
c010831f:	89 e5                	mov    %esp,%ebp
c0108321:	83 ec 38             	sub    $0x38,%esp
    // 获取内存映射列表的头指针
    list_entry_t *list = &(mm->mmap_list), *le;
c0108324:	8b 45 08             	mov    0x8(%ebp),%eax
c0108327:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历内存映射列表，直到回到起点
    while ((le = list_next(list)) != list) {
c010832a:	eb 38                	jmp    c0108364 <mm_destroy+0x46>
c010832c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010832f:	89 45 ec             	mov    %eax,-0x14(%ebp)
    __list_del(listelm->prev, listelm->next);
c0108332:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108335:	8b 40 04             	mov    0x4(%eax),%eax
c0108338:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010833b:	8b 12                	mov    (%edx),%edx
c010833d:	89 55 e8             	mov    %edx,-0x18(%ebp)
c0108340:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    prev->next = next;
c0108343:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108346:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0108349:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c010834c:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010834f:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0108352:	89 10                	mov    %edx,(%eax)
}
c0108354:	90                   	nop
}
c0108355:	90                   	nop
        // 从列表中删除当前虚拟内存区域的项
        list_del(le);
        // 释放虚拟内存区域结构的内存
        kfree(le2vma(le, list_link));
c0108356:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108359:	83 e8 10             	sub    $0x10,%eax
c010835c:	89 04 24             	mov    %eax,(%esp)
c010835f:	e8 a9 c9 ff ff       	call   c0104d0d <kfree>
c0108364:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108367:	89 45 e0             	mov    %eax,-0x20(%ebp)
    return listelm->next;
c010836a:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010836d:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(list)) != list) {
c0108370:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108373:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108376:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0108379:	75 b1                	jne    c010832c <mm_destroy+0xe>
        //kfree(le2vma(le, list_link), sizeof(struct vma_struct));  //kfree vma        
    }
    // 释放内存管理结构本身的内存
    kfree(mm); //kfree mm
c010837b:	8b 45 08             	mov    0x8(%ebp),%eax
c010837e:	89 04 24             	mov    %eax,(%esp)
c0108381:	e8 87 c9 ff ff       	call   c0104d0d <kfree>
    //kfree(mm, sizeof(struct mm_struct)); //kfree mm
    // 将指针设置为NULL，表示该结构已被销毁
    mm=NULL;
c0108386:	c7 45 08 00 00 00 00 	movl   $0x0,0x8(%ebp)
}
c010838d:	90                   	nop
c010838e:	89 ec                	mov    %ebp,%esp
c0108390:	5d                   	pop    %ebp
c0108391:	c3                   	ret    

c0108392 <mm_map>:

int
mm_map(struct mm_struct *mm, uintptr_t addr, size_t len, uint32_t vm_flags,
       struct vma_struct **vma_store) {
c0108392:	55                   	push   %ebp
c0108393:	89 e5                	mov    %esp,%ebp
c0108395:	83 ec 38             	sub    $0x38,%esp
    uintptr_t start = ROUNDDOWN(addr, PGSIZE), end = ROUNDUP(addr + len, PGSIZE);
c0108398:	8b 45 0c             	mov    0xc(%ebp),%eax
c010839b:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010839e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01083a1:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c01083a6:	89 45 ec             	mov    %eax,-0x14(%ebp)
c01083a9:	c7 45 e8 00 10 00 00 	movl   $0x1000,-0x18(%ebp)
c01083b0:	8b 55 0c             	mov    0xc(%ebp),%edx
c01083b3:	8b 45 10             	mov    0x10(%ebp),%eax
c01083b6:	01 c2                	add    %eax,%edx
c01083b8:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01083bb:	01 d0                	add    %edx,%eax
c01083bd:	48                   	dec    %eax
c01083be:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c01083c1:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01083c4:	ba 00 00 00 00       	mov    $0x0,%edx
c01083c9:	f7 75 e8             	divl   -0x18(%ebp)
c01083cc:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01083cf:	29 d0                	sub    %edx,%eax
c01083d1:	89 45 e0             	mov    %eax,-0x20(%ebp)
    if (!USER_ACCESS(start, end)) {
c01083d4:	81 7d ec ff ff 1f 00 	cmpl   $0x1fffff,-0x14(%ebp)
c01083db:	76 11                	jbe    c01083ee <mm_map+0x5c>
c01083dd:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01083e0:	3b 45 e0             	cmp    -0x20(%ebp),%eax
c01083e3:	73 09                	jae    c01083ee <mm_map+0x5c>
c01083e5:	81 7d e0 00 00 00 b0 	cmpl   $0xb0000000,-0x20(%ebp)
c01083ec:	76 0a                	jbe    c01083f8 <mm_map+0x66>
        return -E_INVAL;
c01083ee:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
c01083f3:	e9 b0 00 00 00       	jmp    c01084a8 <mm_map+0x116>
    }

    assert(mm != NULL);
c01083f8:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c01083fc:	75 24                	jne    c0108422 <mm_map+0x90>
c01083fe:	c7 44 24 0c 85 db 10 	movl   $0xc010db85,0xc(%esp)
c0108405:	c0 
c0108406:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c010840d:	c0 
c010840e:	c7 44 24 04 fd 00 00 	movl   $0xfd,0x4(%esp)
c0108415:	00 
c0108416:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c010841d:	e8 19 89 ff ff       	call   c0100d3b <__panic>

    int ret = -E_INVAL;
c0108422:	c7 45 f4 fd ff ff ff 	movl   $0xfffffffd,-0xc(%ebp)

    struct vma_struct *vma;
    if ((vma = find_vma(mm, start)) != NULL && end > vma->vm_start) {
c0108429:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010842c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108430:	8b 45 08             	mov    0x8(%ebp),%eax
c0108433:	89 04 24             	mov    %eax,(%esp)
c0108436:	e8 53 fc ff ff       	call   c010808e <find_vma>
c010843b:	89 45 dc             	mov    %eax,-0x24(%ebp)
c010843e:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0108442:	74 0b                	je     c010844f <mm_map+0xbd>
c0108444:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108447:	8b 40 04             	mov    0x4(%eax),%eax
c010844a:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c010844d:	77 52                	ja     c01084a1 <mm_map+0x10f>
        goto out;
    }
    ret = -E_NO_MEM;
c010844f:	c7 45 f4 fc ff ff ff 	movl   $0xfffffffc,-0xc(%ebp)

    if ((vma = vma_create(start, end, vm_flags)) == NULL) {
c0108456:	8b 45 14             	mov    0x14(%ebp),%eax
c0108459:	89 44 24 08          	mov    %eax,0x8(%esp)
c010845d:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108460:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108464:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108467:	89 04 24             	mov    %eax,(%esp)
c010846a:	e8 e2 fb ff ff       	call   c0108051 <vma_create>
c010846f:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0108472:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0108476:	74 2c                	je     c01084a4 <mm_map+0x112>
        goto out;
    }
    insert_vma_struct(mm, vma);
c0108478:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010847b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010847f:	8b 45 08             	mov    0x8(%ebp),%eax
c0108482:	89 04 24             	mov    %eax,(%esp)
c0108485:	e8 5e fd ff ff       	call   c01081e8 <insert_vma_struct>
    if (vma_store != NULL) {
c010848a:	83 7d 18 00          	cmpl   $0x0,0x18(%ebp)
c010848e:	74 08                	je     c0108498 <mm_map+0x106>
        *vma_store = vma;
c0108490:	8b 45 18             	mov    0x18(%ebp),%eax
c0108493:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0108496:	89 10                	mov    %edx,(%eax)
    }
    ret = 0;
c0108498:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c010849f:	eb 04                	jmp    c01084a5 <mm_map+0x113>
        goto out;
c01084a1:	90                   	nop
c01084a2:	eb 01                	jmp    c01084a5 <mm_map+0x113>
        goto out;
c01084a4:	90                   	nop

out:
    return ret;
c01084a5:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01084a8:	89 ec                	mov    %ebp,%esp
c01084aa:	5d                   	pop    %ebp
c01084ab:	c3                   	ret    

c01084ac <dup_mmap>:

int
dup_mmap(struct mm_struct *to, struct mm_struct *from) {
c01084ac:	55                   	push   %ebp
c01084ad:	89 e5                	mov    %esp,%ebp
c01084af:	56                   	push   %esi
c01084b0:	53                   	push   %ebx
c01084b1:	83 ec 40             	sub    $0x40,%esp
    assert(to != NULL && from != NULL);
c01084b4:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c01084b8:	74 06                	je     c01084c0 <dup_mmap+0x14>
c01084ba:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c01084be:	75 24                	jne    c01084e4 <dup_mmap+0x38>
c01084c0:	c7 44 24 0c 90 db 10 	movl   $0xc010db90,0xc(%esp)
c01084c7:	c0 
c01084c8:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c01084cf:	c0 
c01084d0:	c7 44 24 04 16 01 00 	movl   $0x116,0x4(%esp)
c01084d7:	00 
c01084d8:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c01084df:	e8 57 88 ff ff       	call   c0100d3b <__panic>
    list_entry_t *list = &(from->mmap_list), *le = list;
c01084e4:	8b 45 0c             	mov    0xc(%ebp),%eax
c01084e7:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01084ea:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01084ed:	89 45 f4             	mov    %eax,-0xc(%ebp)
    while ((le = list_prev(le)) != list) {
c01084f0:	e9 92 00 00 00       	jmp    c0108587 <dup_mmap+0xdb>
        struct vma_struct *vma, *nvma;
        vma = le2vma(le, list_link);
c01084f5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01084f8:	83 e8 10             	sub    $0x10,%eax
c01084fb:	89 45 ec             	mov    %eax,-0x14(%ebp)
        nvma = vma_create(vma->vm_start, vma->vm_end, vma->vm_flags);
c01084fe:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108501:	8b 48 0c             	mov    0xc(%eax),%ecx
c0108504:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108507:	8b 50 08             	mov    0x8(%eax),%edx
c010850a:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010850d:	8b 40 04             	mov    0x4(%eax),%eax
c0108510:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0108514:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108518:	89 04 24             	mov    %eax,(%esp)
c010851b:	e8 31 fb ff ff       	call   c0108051 <vma_create>
c0108520:	89 45 e8             	mov    %eax,-0x18(%ebp)
        if (nvma == NULL) {
c0108523:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0108527:	75 07                	jne    c0108530 <dup_mmap+0x84>
            return -E_NO_MEM;
c0108529:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
c010852e:	eb 76                	jmp    c01085a6 <dup_mmap+0xfa>
        }

        insert_vma_struct(to, nvma);
c0108530:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108533:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108537:	8b 45 08             	mov    0x8(%ebp),%eax
c010853a:	89 04 24             	mov    %eax,(%esp)
c010853d:	e8 a6 fc ff ff       	call   c01081e8 <insert_vma_struct>

        bool share = 0;
c0108542:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
        if (copy_range(to->pgdir, from->pgdir, vma->vm_start, vma->vm_end, share) != 0) {
c0108549:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010854c:	8b 58 08             	mov    0x8(%eax),%ebx
c010854f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108552:	8b 48 04             	mov    0x4(%eax),%ecx
c0108555:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108558:	8b 50 0c             	mov    0xc(%eax),%edx
c010855b:	8b 45 08             	mov    0x8(%ebp),%eax
c010855e:	8b 40 0c             	mov    0xc(%eax),%eax
c0108561:	8b 75 e4             	mov    -0x1c(%ebp),%esi
c0108564:	89 74 24 10          	mov    %esi,0x10(%esp)
c0108568:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c010856c:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0108570:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108574:	89 04 24             	mov    %eax,(%esp)
c0108577:	e8 bb d6 ff ff       	call   c0105c37 <copy_range>
c010857c:	85 c0                	test   %eax,%eax
c010857e:	74 07                	je     c0108587 <dup_mmap+0xdb>
            return -E_NO_MEM;
c0108580:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
c0108585:	eb 1f                	jmp    c01085a6 <dup_mmap+0xfa>
c0108587:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010858a:	89 45 e0             	mov    %eax,-0x20(%ebp)
    return listelm->prev;
c010858d:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108590:	8b 00                	mov    (%eax),%eax
    while ((le = list_prev(le)) != list) {
c0108592:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108595:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108598:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c010859b:	0f 85 54 ff ff ff    	jne    c01084f5 <dup_mmap+0x49>
        }
    }
    return 0;
c01085a1:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01085a6:	83 c4 40             	add    $0x40,%esp
c01085a9:	5b                   	pop    %ebx
c01085aa:	5e                   	pop    %esi
c01085ab:	5d                   	pop    %ebp
c01085ac:	c3                   	ret    

c01085ad <exit_mmap>:

void
exit_mmap(struct mm_struct *mm) {
c01085ad:	55                   	push   %ebp
c01085ae:	89 e5                	mov    %esp,%ebp
c01085b0:	83 ec 38             	sub    $0x38,%esp
    assert(mm != NULL && mm_count(mm) == 0);
c01085b3:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c01085b7:	74 0f                	je     c01085c8 <exit_mmap+0x1b>
c01085b9:	8b 45 08             	mov    0x8(%ebp),%eax
c01085bc:	89 04 24             	mov    %eax,(%esp)
c01085bf:	e8 75 f9 ff ff       	call   c0107f39 <mm_count>
c01085c4:	85 c0                	test   %eax,%eax
c01085c6:	74 24                	je     c01085ec <exit_mmap+0x3f>
c01085c8:	c7 44 24 0c ac db 10 	movl   $0xc010dbac,0xc(%esp)
c01085cf:	c0 
c01085d0:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c01085d7:	c0 
c01085d8:	c7 44 24 04 2c 01 00 	movl   $0x12c,0x4(%esp)
c01085df:	00 
c01085e0:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c01085e7:	e8 4f 87 ff ff       	call   c0100d3b <__panic>
    pde_t *pgdir = mm->pgdir;
c01085ec:	8b 45 08             	mov    0x8(%ebp),%eax
c01085ef:	8b 40 0c             	mov    0xc(%eax),%eax
c01085f2:	89 45 f0             	mov    %eax,-0x10(%ebp)
    list_entry_t *list = &(mm->mmap_list), *le = list;
c01085f5:	8b 45 08             	mov    0x8(%ebp),%eax
c01085f8:	89 45 ec             	mov    %eax,-0x14(%ebp)
c01085fb:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01085fe:	89 45 f4             	mov    %eax,-0xc(%ebp)
    while ((le = list_next(le)) != list) {
c0108601:	eb 28                	jmp    c010862b <exit_mmap+0x7e>
        struct vma_struct *vma = le2vma(le, list_link);
c0108603:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108606:	83 e8 10             	sub    $0x10,%eax
c0108609:	89 45 e4             	mov    %eax,-0x1c(%ebp)
        unmap_range(pgdir, vma->vm_start, vma->vm_end);
c010860c:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010860f:	8b 50 08             	mov    0x8(%eax),%edx
c0108612:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108615:	8b 40 04             	mov    0x4(%eax),%eax
c0108618:	89 54 24 08          	mov    %edx,0x8(%esp)
c010861c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108620:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108623:	89 04 24             	mov    %eax,(%esp)
c0108626:	e8 0b d4 ff ff       	call   c0105a36 <unmap_range>
c010862b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010862e:	89 45 e0             	mov    %eax,-0x20(%ebp)
    return listelm->next;
c0108631:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108634:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != list) {
c0108637:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010863a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010863d:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0108640:	75 c1                	jne    c0108603 <exit_mmap+0x56>
    }
    while ((le = list_next(le)) != list) {
c0108642:	eb 28                	jmp    c010866c <exit_mmap+0xbf>
        struct vma_struct *vma = le2vma(le, list_link);
c0108644:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108647:	83 e8 10             	sub    $0x10,%eax
c010864a:	89 45 e8             	mov    %eax,-0x18(%ebp)
        exit_range(pgdir, vma->vm_start, vma->vm_end);
c010864d:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108650:	8b 50 08             	mov    0x8(%eax),%edx
c0108653:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108656:	8b 40 04             	mov    0x4(%eax),%eax
c0108659:	89 54 24 08          	mov    %edx,0x8(%esp)
c010865d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108661:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108664:	89 04 24             	mov    %eax,(%esp)
c0108667:	e8 c1 d4 ff ff       	call   c0105b2d <exit_range>
c010866c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010866f:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0108672:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108675:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != list) {
c0108678:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010867b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010867e:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0108681:	75 c1                	jne    c0108644 <exit_mmap+0x97>
    }
}
c0108683:	90                   	nop
c0108684:	90                   	nop
c0108685:	89 ec                	mov    %ebp,%esp
c0108687:	5d                   	pop    %ebp
c0108688:	c3                   	ret    

c0108689 <copy_from_user>:

bool
copy_from_user(struct mm_struct *mm, void *dst, const void *src, size_t len, bool writable) {
c0108689:	55                   	push   %ebp
c010868a:	89 e5                	mov    %esp,%ebp
c010868c:	83 ec 18             	sub    $0x18,%esp
    if (!user_mem_check(mm, (uintptr_t)src, len, writable)) {
c010868f:	8b 45 10             	mov    0x10(%ebp),%eax
c0108692:	8b 55 18             	mov    0x18(%ebp),%edx
c0108695:	89 54 24 0c          	mov    %edx,0xc(%esp)
c0108699:	8b 55 14             	mov    0x14(%ebp),%edx
c010869c:	89 54 24 08          	mov    %edx,0x8(%esp)
c01086a0:	89 44 24 04          	mov    %eax,0x4(%esp)
c01086a4:	8b 45 08             	mov    0x8(%ebp),%eax
c01086a7:	89 04 24             	mov    %eax,(%esp)
c01086aa:	e8 ab 09 00 00       	call   c010905a <user_mem_check>
c01086af:	85 c0                	test   %eax,%eax
c01086b1:	75 07                	jne    c01086ba <copy_from_user+0x31>
        return 0;
c01086b3:	b8 00 00 00 00       	mov    $0x0,%eax
c01086b8:	eb 1e                	jmp    c01086d8 <copy_from_user+0x4f>
    }
    memcpy(dst, src, len);
c01086ba:	8b 45 14             	mov    0x14(%ebp),%eax
c01086bd:	89 44 24 08          	mov    %eax,0x8(%esp)
c01086c1:	8b 45 10             	mov    0x10(%ebp),%eax
c01086c4:	89 44 24 04          	mov    %eax,0x4(%esp)
c01086c8:	8b 45 0c             	mov    0xc(%ebp),%eax
c01086cb:	89 04 24             	mov    %eax,(%esp)
c01086ce:	e8 03 38 00 00       	call   c010bed6 <memcpy>
    return 1;
c01086d3:	b8 01 00 00 00       	mov    $0x1,%eax
}
c01086d8:	89 ec                	mov    %ebp,%esp
c01086da:	5d                   	pop    %ebp
c01086db:	c3                   	ret    

c01086dc <copy_to_user>:

bool
copy_to_user(struct mm_struct *mm, void *dst, const void *src, size_t len) {
c01086dc:	55                   	push   %ebp
c01086dd:	89 e5                	mov    %esp,%ebp
c01086df:	83 ec 18             	sub    $0x18,%esp
    if (!user_mem_check(mm, (uintptr_t)dst, len, 1)) {
c01086e2:	8b 45 0c             	mov    0xc(%ebp),%eax
c01086e5:	c7 44 24 0c 01 00 00 	movl   $0x1,0xc(%esp)
c01086ec:	00 
c01086ed:	8b 55 14             	mov    0x14(%ebp),%edx
c01086f0:	89 54 24 08          	mov    %edx,0x8(%esp)
c01086f4:	89 44 24 04          	mov    %eax,0x4(%esp)
c01086f8:	8b 45 08             	mov    0x8(%ebp),%eax
c01086fb:	89 04 24             	mov    %eax,(%esp)
c01086fe:	e8 57 09 00 00       	call   c010905a <user_mem_check>
c0108703:	85 c0                	test   %eax,%eax
c0108705:	75 07                	jne    c010870e <copy_to_user+0x32>
        return 0;
c0108707:	b8 00 00 00 00       	mov    $0x0,%eax
c010870c:	eb 1e                	jmp    c010872c <copy_to_user+0x50>
    }
    memcpy(dst, src, len);
c010870e:	8b 45 14             	mov    0x14(%ebp),%eax
c0108711:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108715:	8b 45 10             	mov    0x10(%ebp),%eax
c0108718:	89 44 24 04          	mov    %eax,0x4(%esp)
c010871c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010871f:	89 04 24             	mov    %eax,(%esp)
c0108722:	e8 af 37 00 00       	call   c010bed6 <memcpy>
    return 1;
c0108727:	b8 01 00 00 00       	mov    $0x1,%eax
}
c010872c:	89 ec                	mov    %ebp,%esp
c010872e:	5d                   	pop    %ebp
c010872f:	c3                   	ret    

c0108730 <vmm_init>:
/**
 * 初始化虚拟内存管理(VMM)系统。
 * 此函数通过执行一系列检查来确保VMM系统可以正确初始化和运行。
 */
void
vmm_init(void) {
c0108730:	55                   	push   %ebp
c0108731:	89 e5                	mov    %esp,%ebp
c0108733:	83 ec 08             	sub    $0x8,%esp
    // 检查VMM系统的状态和环境，以确保其能够正常工作。
    check_vmm();
c0108736:	e8 05 00 00 00       	call   c0108740 <check_vmm>
}
c010873b:	90                   	nop
c010873c:	89 ec                	mov    %ebp,%esp
c010873e:	5d                   	pop    %ebp
c010873f:	c3                   	ret    

c0108740 <check_vmm>:
 * 此函数的目的是确保虚拟内存管理系统的正确性通过检查内存区域结构（VMA）、页面故障处理以及免费页面计数的 consistency 来实现
 * 它首先保存当前的免费页面数量，然后执行与 VMA 和页面故障相关的检查，最后确认免费页面数量未发生变化
 * 这是为了确保在检查过程中，内存状态没有因为错误或意外的修改而改变，从而验证内存管理的正确性
 */
static void
check_vmm(void) {
c0108740:	55                   	push   %ebp
c0108741:	89 e5                	mov    %esp,%ebp
c0108743:	83 ec 28             	sub    $0x28,%esp
    // 保存当前的免费页面数量，用于后续的 consistency 检查
    size_t nr_free_pages_store = nr_free_pages();
c0108746:	e8 d8 ca ff ff       	call   c0105223 <nr_free_pages>
c010874b:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查虚拟内存区域（VMA）结构的正确性
    check_vma_struct();
c010874e:	e8 16 00 00 00       	call   c0108769 <check_vma_struct>
    // 检查页面故障处理的正确性
    check_pgfault();
c0108753:	e8 a5 04 00 00       	call   c0108bfd <check_pgfault>
    // 确保在检查过程中免费页面数量未发生变化，表明内存管理操作是正确的
    // assert(nr_free_pages_store == nr_free_pages());
    // 如果所有检查都通过，输出成功信息
    cprintf("check_vmm() succeeded.\n");
c0108758:	c7 04 24 cc db 10 c0 	movl   $0xc010dbcc,(%esp)
c010875f:	e8 14 7c ff ff       	call   c0100378 <cprintf>
}
c0108764:	90                   	nop
c0108765:	89 ec                	mov    %ebp,%esp
c0108767:	5d                   	pop    %ebp
c0108768:	c3                   	ret    

c0108769 <check_vma_struct>:

//测试虚拟内存区域（VMA）结构的创建、插入和查找功能。
static void
check_vma_struct(void) {
c0108769:	55                   	push   %ebp
c010876a:	89 e5                	mov    %esp,%ebp
c010876c:	83 ec 68             	sub    $0x68,%esp
    // 记录当前空闲页面数量
    size_t nr_free_pages_store = nr_free_pages();
c010876f:	e8 af ca ff ff       	call   c0105223 <nr_free_pages>
c0108774:	89 45 ec             	mov    %eax,-0x14(%ebp)

    struct mm_struct *mm = mm_create();// 创建内存管理结构 mm
c0108777:	e8 39 f8 ff ff       	call   c0107fb5 <mm_create>
c010877c:	89 45 e8             	mov    %eax,-0x18(%ebp)
    assert(mm != NULL);// 确保 mm 不为 NULL
c010877f:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0108783:	75 24                	jne    c01087a9 <check_vma_struct+0x40>
c0108785:	c7 44 24 0c 85 db 10 	movl   $0xc010db85,0xc(%esp)
c010878c:	c0 
c010878d:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108794:	c0 
c0108795:	c7 44 24 04 74 01 00 	movl   $0x174,0x4(%esp)
c010879c:	00 
c010879d:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c01087a4:	e8 92 85 ff ff       	call   c0100d3b <__panic>

    int step1 = 10, step2 = step1 * 10;// 定义两个步骤的步数
c01087a9:	c7 45 e4 0a 00 00 00 	movl   $0xa,-0x1c(%ebp)
c01087b0:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01087b3:	89 d0                	mov    %edx,%eax
c01087b5:	c1 e0 02             	shl    $0x2,%eax
c01087b8:	01 d0                	add    %edx,%eax
c01087ba:	01 c0                	add    %eax,%eax
c01087bc:	89 45 e0             	mov    %eax,-0x20(%ebp)

    int i;
    for (i = step1; i >= 1; i --) {// 第一步：创建并插入10个VMA
c01087bf:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01087c2:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01087c5:	eb 6f                	jmp    c0108836 <check_vma_struct+0xcd>
        // 创建 VMA 结构
        struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0);
c01087c7:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01087ca:	89 d0                	mov    %edx,%eax
c01087cc:	c1 e0 02             	shl    $0x2,%eax
c01087cf:	01 d0                	add    %edx,%eax
c01087d1:	83 c0 02             	add    $0x2,%eax
c01087d4:	89 c1                	mov    %eax,%ecx
c01087d6:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01087d9:	89 d0                	mov    %edx,%eax
c01087db:	c1 e0 02             	shl    $0x2,%eax
c01087de:	01 d0                	add    %edx,%eax
c01087e0:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01087e7:	00 
c01087e8:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c01087ec:	89 04 24             	mov    %eax,(%esp)
c01087ef:	e8 5d f8 ff ff       	call   c0108051 <vma_create>
c01087f4:	89 45 bc             	mov    %eax,-0x44(%ebp)
        assert(vma != NULL);// 确保 VMA 不为 NULL
c01087f7:	83 7d bc 00          	cmpl   $0x0,-0x44(%ebp)
c01087fb:	75 24                	jne    c0108821 <check_vma_struct+0xb8>
c01087fd:	c7 44 24 0c e4 db 10 	movl   $0xc010dbe4,0xc(%esp)
c0108804:	c0 
c0108805:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c010880c:	c0 
c010880d:	c7 44 24 04 7c 01 00 	movl   $0x17c,0x4(%esp)
c0108814:	00 
c0108815:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c010881c:	e8 1a 85 ff ff       	call   c0100d3b <__panic>
        insert_vma_struct(mm, vma); //将 VMA 插入到 mm 中
c0108821:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0108824:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108828:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010882b:	89 04 24             	mov    %eax,(%esp)
c010882e:	e8 b5 f9 ff ff       	call   c01081e8 <insert_vma_struct>
    for (i = step1; i >= 1; i --) {// 第一步：创建并插入10个VMA
c0108833:	ff 4d f4             	decl   -0xc(%ebp)
c0108836:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010883a:	7f 8b                	jg     c01087c7 <check_vma_struct+0x5e>
    }

    for (i = step1 + 1; i <= step2; i ++) {// 第二步：创建并插入90个VMA
c010883c:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010883f:	40                   	inc    %eax
c0108840:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108843:	eb 6f                	jmp    c01088b4 <check_vma_struct+0x14b>
        // 创建 VMA 结构
        struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0);
c0108845:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108848:	89 d0                	mov    %edx,%eax
c010884a:	c1 e0 02             	shl    $0x2,%eax
c010884d:	01 d0                	add    %edx,%eax
c010884f:	83 c0 02             	add    $0x2,%eax
c0108852:	89 c1                	mov    %eax,%ecx
c0108854:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108857:	89 d0                	mov    %edx,%eax
c0108859:	c1 e0 02             	shl    $0x2,%eax
c010885c:	01 d0                	add    %edx,%eax
c010885e:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0108865:	00 
c0108866:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c010886a:	89 04 24             	mov    %eax,(%esp)
c010886d:	e8 df f7 ff ff       	call   c0108051 <vma_create>
c0108872:	89 45 c0             	mov    %eax,-0x40(%ebp)
        assert(vma != NULL);// 确保 VMA 不为 NULL
c0108875:	83 7d c0 00          	cmpl   $0x0,-0x40(%ebp)
c0108879:	75 24                	jne    c010889f <check_vma_struct+0x136>
c010887b:	c7 44 24 0c e4 db 10 	movl   $0xc010dbe4,0xc(%esp)
c0108882:	c0 
c0108883:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c010888a:	c0 
c010888b:	c7 44 24 04 83 01 00 	movl   $0x183,0x4(%esp)
c0108892:	00 
c0108893:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c010889a:	e8 9c 84 ff ff       	call   c0100d3b <__panic>
        insert_vma_struct(mm, vma);// 将 VMA 插入到 mm 中
c010889f:	8b 45 c0             	mov    -0x40(%ebp),%eax
c01088a2:	89 44 24 04          	mov    %eax,0x4(%esp)
c01088a6:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01088a9:	89 04 24             	mov    %eax,(%esp)
c01088ac:	e8 37 f9 ff ff       	call   c01081e8 <insert_vma_struct>
    for (i = step1 + 1; i <= step2; i ++) {// 第二步：创建并插入90个VMA
c01088b1:	ff 45 f4             	incl   -0xc(%ebp)
c01088b4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01088b7:	3b 45 e0             	cmp    -0x20(%ebp),%eax
c01088ba:	7e 89                	jle    c0108845 <check_vma_struct+0xdc>
    }
    // 获取 VMA 链表的第一个节点
    list_entry_t *le = list_next(&(mm->mmap_list));
c01088bc:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01088bf:	89 45 b8             	mov    %eax,-0x48(%ebp)
c01088c2:	8b 45 b8             	mov    -0x48(%ebp),%eax
c01088c5:	8b 40 04             	mov    0x4(%eax),%eax
c01088c8:	89 45 f0             	mov    %eax,-0x10(%ebp)

    for (i = 1; i <= step2; i ++) {// 验证插入顺序
c01088cb:	c7 45 f4 01 00 00 00 	movl   $0x1,-0xc(%ebp)
c01088d2:	e9 96 00 00 00       	jmp    c010896d <check_vma_struct+0x204>
        assert(le != &(mm->mmap_list));// 确保节点不为空
c01088d7:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01088da:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01088dd:	75 24                	jne    c0108903 <check_vma_struct+0x19a>
c01088df:	c7 44 24 0c f0 db 10 	movl   $0xc010dbf0,0xc(%esp)
c01088e6:	c0 
c01088e7:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c01088ee:	c0 
c01088ef:	c7 44 24 04 8a 01 00 	movl   $0x18a,0x4(%esp)
c01088f6:	00 
c01088f7:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c01088fe:	e8 38 84 ff ff       	call   c0100d3b <__panic>
        struct vma_struct *mmap = le2vma(le, list_link);// 将链表节点转换为 VMA 结构
c0108903:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108906:	83 e8 10             	sub    $0x10,%eax
c0108909:	89 45 c4             	mov    %eax,-0x3c(%ebp)
        // 确认 VMA 的起始和结束地址
        assert(mmap->vm_start == i * 5 && mmap->vm_end == i * 5 + 2);
c010890c:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c010890f:	8b 48 04             	mov    0x4(%eax),%ecx
c0108912:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108915:	89 d0                	mov    %edx,%eax
c0108917:	c1 e0 02             	shl    $0x2,%eax
c010891a:	01 d0                	add    %edx,%eax
c010891c:	39 c1                	cmp    %eax,%ecx
c010891e:	75 17                	jne    c0108937 <check_vma_struct+0x1ce>
c0108920:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0108923:	8b 48 08             	mov    0x8(%eax),%ecx
c0108926:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108929:	89 d0                	mov    %edx,%eax
c010892b:	c1 e0 02             	shl    $0x2,%eax
c010892e:	01 d0                	add    %edx,%eax
c0108930:	83 c0 02             	add    $0x2,%eax
c0108933:	39 c1                	cmp    %eax,%ecx
c0108935:	74 24                	je     c010895b <check_vma_struct+0x1f2>
c0108937:	c7 44 24 0c 08 dc 10 	movl   $0xc010dc08,0xc(%esp)
c010893e:	c0 
c010893f:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108946:	c0 
c0108947:	c7 44 24 04 8d 01 00 	movl   $0x18d,0x4(%esp)
c010894e:	00 
c010894f:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108956:	e8 e0 83 ff ff       	call   c0100d3b <__panic>
c010895b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010895e:	89 45 b4             	mov    %eax,-0x4c(%ebp)
c0108961:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0108964:	8b 40 04             	mov    0x4(%eax),%eax
        le = list_next(le);// 移动到下一个节点
c0108967:	89 45 f0             	mov    %eax,-0x10(%ebp)
    for (i = 1; i <= step2; i ++) {// 验证插入顺序
c010896a:	ff 45 f4             	incl   -0xc(%ebp)
c010896d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108970:	3b 45 e0             	cmp    -0x20(%ebp),%eax
c0108973:	0f 8e 5e ff ff ff    	jle    c01088d7 <check_vma_struct+0x16e>
    }

    for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA
c0108979:	c7 45 f4 05 00 00 00 	movl   $0x5,-0xc(%ebp)
c0108980:	e9 cb 01 00 00       	jmp    c0108b50 <check_vma_struct+0x3e7>
        struct vma_struct *vma1 = find_vma(mm, i);// 查找地址 i 处的 VMA
c0108985:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108988:	89 44 24 04          	mov    %eax,0x4(%esp)
c010898c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010898f:	89 04 24             	mov    %eax,(%esp)
c0108992:	e8 f7 f6 ff ff       	call   c010808e <find_vma>
c0108997:	89 45 d8             	mov    %eax,-0x28(%ebp)
        assert(vma1 != NULL);// 确保找到 VMA
c010899a:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c010899e:	75 24                	jne    c01089c4 <check_vma_struct+0x25b>
c01089a0:	c7 44 24 0c 3d dc 10 	movl   $0xc010dc3d,0xc(%esp)
c01089a7:	c0 
c01089a8:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c01089af:	c0 
c01089b0:	c7 44 24 04 93 01 00 	movl   $0x193,0x4(%esp)
c01089b7:	00 
c01089b8:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c01089bf:	e8 77 83 ff ff       	call   c0100d3b <__panic>
        // 查找地址 i + 1 处的 VMA
        struct vma_struct *vma2 = find_vma(mm, i+1);
c01089c4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01089c7:	40                   	inc    %eax
c01089c8:	89 44 24 04          	mov    %eax,0x4(%esp)
c01089cc:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01089cf:	89 04 24             	mov    %eax,(%esp)
c01089d2:	e8 b7 f6 ff ff       	call   c010808e <find_vma>
c01089d7:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        assert(vma2 != NULL);// 确保找到 VMA
c01089da:	83 7d d4 00          	cmpl   $0x0,-0x2c(%ebp)
c01089de:	75 24                	jne    c0108a04 <check_vma_struct+0x29b>
c01089e0:	c7 44 24 0c 4a dc 10 	movl   $0xc010dc4a,0xc(%esp)
c01089e7:	c0 
c01089e8:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c01089ef:	c0 
c01089f0:	c7 44 24 04 96 01 00 	movl   $0x196,0x4(%esp)
c01089f7:	00 
c01089f8:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c01089ff:	e8 37 83 ff ff       	call   c0100d3b <__panic>
        // 查找地址 i + 2 处的 VMA
        struct vma_struct *vma3 = find_vma(mm, i+2);
c0108a04:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108a07:	83 c0 02             	add    $0x2,%eax
c0108a0a:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108a0e:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108a11:	89 04 24             	mov    %eax,(%esp)
c0108a14:	e8 75 f6 ff ff       	call   c010808e <find_vma>
c0108a19:	89 45 d0             	mov    %eax,-0x30(%ebp)
        assert(vma3 == NULL);// 确保未找到 VMA
c0108a1c:	83 7d d0 00          	cmpl   $0x0,-0x30(%ebp)
c0108a20:	74 24                	je     c0108a46 <check_vma_struct+0x2dd>
c0108a22:	c7 44 24 0c 57 dc 10 	movl   $0xc010dc57,0xc(%esp)
c0108a29:	c0 
c0108a2a:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108a31:	c0 
c0108a32:	c7 44 24 04 99 01 00 	movl   $0x199,0x4(%esp)
c0108a39:	00 
c0108a3a:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108a41:	e8 f5 82 ff ff       	call   c0100d3b <__panic>
        // 查找地址 i + 3 处的 VMA
        struct vma_struct *vma4 = find_vma(mm, i+3);
c0108a46:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108a49:	83 c0 03             	add    $0x3,%eax
c0108a4c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108a50:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108a53:	89 04 24             	mov    %eax,(%esp)
c0108a56:	e8 33 f6 ff ff       	call   c010808e <find_vma>
c0108a5b:	89 45 cc             	mov    %eax,-0x34(%ebp)
        assert(vma4 == NULL);// 确保未找到 VMA
c0108a5e:	83 7d cc 00          	cmpl   $0x0,-0x34(%ebp)
c0108a62:	74 24                	je     c0108a88 <check_vma_struct+0x31f>
c0108a64:	c7 44 24 0c 64 dc 10 	movl   $0xc010dc64,0xc(%esp)
c0108a6b:	c0 
c0108a6c:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108a73:	c0 
c0108a74:	c7 44 24 04 9c 01 00 	movl   $0x19c,0x4(%esp)
c0108a7b:	00 
c0108a7c:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108a83:	e8 b3 82 ff ff       	call   c0100d3b <__panic>
        // 查找地址 i + 4 处的 VMA
        struct vma_struct *vma5 = find_vma(mm, i+4);
c0108a88:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108a8b:	83 c0 04             	add    $0x4,%eax
c0108a8e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108a92:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108a95:	89 04 24             	mov    %eax,(%esp)
c0108a98:	e8 f1 f5 ff ff       	call   c010808e <find_vma>
c0108a9d:	89 45 c8             	mov    %eax,-0x38(%ebp)
        assert(vma5 == NULL);// 确保未找到 VMA
c0108aa0:	83 7d c8 00          	cmpl   $0x0,-0x38(%ebp)
c0108aa4:	74 24                	je     c0108aca <check_vma_struct+0x361>
c0108aa6:	c7 44 24 0c 71 dc 10 	movl   $0xc010dc71,0xc(%esp)
c0108aad:	c0 
c0108aae:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108ab5:	c0 
c0108ab6:	c7 44 24 04 9f 01 00 	movl   $0x19f,0x4(%esp)
c0108abd:	00 
c0108abe:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108ac5:	e8 71 82 ff ff       	call   c0100d3b <__panic>
        // 确认 VMA1 的起始和结束地址
        assert(vma1->vm_start == i  && vma1->vm_end == i  + 2);
c0108aca:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0108acd:	8b 50 04             	mov    0x4(%eax),%edx
c0108ad0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108ad3:	39 c2                	cmp    %eax,%edx
c0108ad5:	75 10                	jne    c0108ae7 <check_vma_struct+0x37e>
c0108ad7:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0108ada:	8b 40 08             	mov    0x8(%eax),%eax
c0108add:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108ae0:	83 c2 02             	add    $0x2,%edx
c0108ae3:	39 d0                	cmp    %edx,%eax
c0108ae5:	74 24                	je     c0108b0b <check_vma_struct+0x3a2>
c0108ae7:	c7 44 24 0c 80 dc 10 	movl   $0xc010dc80,0xc(%esp)
c0108aee:	c0 
c0108aef:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108af6:	c0 
c0108af7:	c7 44 24 04 a1 01 00 	movl   $0x1a1,0x4(%esp)
c0108afe:	00 
c0108aff:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108b06:	e8 30 82 ff ff       	call   c0100d3b <__panic>
        // 确认 VMA2 的起始和结束地址
        assert(vma2->vm_start == i  && vma2->vm_end == i  + 2);
c0108b0b:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0108b0e:	8b 50 04             	mov    0x4(%eax),%edx
c0108b11:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108b14:	39 c2                	cmp    %eax,%edx
c0108b16:	75 10                	jne    c0108b28 <check_vma_struct+0x3bf>
c0108b18:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0108b1b:	8b 40 08             	mov    0x8(%eax),%eax
c0108b1e:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108b21:	83 c2 02             	add    $0x2,%edx
c0108b24:	39 d0                	cmp    %edx,%eax
c0108b26:	74 24                	je     c0108b4c <check_vma_struct+0x3e3>
c0108b28:	c7 44 24 0c b0 dc 10 	movl   $0xc010dcb0,0xc(%esp)
c0108b2f:	c0 
c0108b30:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108b37:	c0 
c0108b38:	c7 44 24 04 a3 01 00 	movl   $0x1a3,0x4(%esp)
c0108b3f:	00 
c0108b40:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108b47:	e8 ef 81 ff ff       	call   c0100d3b <__panic>
    for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA
c0108b4c:	83 45 f4 05          	addl   $0x5,-0xc(%ebp)
c0108b50:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0108b53:	89 d0                	mov    %edx,%eax
c0108b55:	c1 e0 02             	shl    $0x2,%eax
c0108b58:	01 d0                	add    %edx,%eax
c0108b5a:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0108b5d:	0f 8e 22 fe ff ff    	jle    c0108985 <check_vma_struct+0x21c>
    }
    // 检查小于5的地址范围内是否存在 VMA
    for (i =4; i>=0; i--) {
c0108b63:	c7 45 f4 04 00 00 00 	movl   $0x4,-0xc(%ebp)
c0108b6a:	eb 6f                	jmp    c0108bdb <check_vma_struct+0x472>
        // 查找地址 i 处的 VMA
        struct vma_struct *vma_below_5= find_vma(mm,i);
c0108b6c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108b6f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108b73:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108b76:	89 04 24             	mov    %eax,(%esp)
c0108b79:	e8 10 f5 ff ff       	call   c010808e <find_vma>
c0108b7e:	89 45 dc             	mov    %eax,-0x24(%ebp)
        if (vma_below_5 != NULL ) {// 如果找到 VMA
c0108b81:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0108b85:	74 27                	je     c0108bae <check_vma_struct+0x445>
           cprintf("vma_below_5: i %x, start %x, end %x\n",i, vma_below_5->vm_start, vma_below_5->vm_end); 
c0108b87:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108b8a:	8b 50 08             	mov    0x8(%eax),%edx
c0108b8d:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108b90:	8b 40 04             	mov    0x4(%eax),%eax
c0108b93:	89 54 24 0c          	mov    %edx,0xc(%esp)
c0108b97:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108b9b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108b9e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108ba2:	c7 04 24 e0 dc 10 c0 	movl   $0xc010dce0,(%esp)
c0108ba9:	e8 ca 77 ff ff       	call   c0100378 <cprintf>
        }
        assert(vma_below_5 == NULL);// 确保未找到 VMA
c0108bae:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0108bb2:	74 24                	je     c0108bd8 <check_vma_struct+0x46f>
c0108bb4:	c7 44 24 0c 05 dd 10 	movl   $0xc010dd05,0xc(%esp)
c0108bbb:	c0 
c0108bbc:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108bc3:	c0 
c0108bc4:	c7 44 24 04 ac 01 00 	movl   $0x1ac,0x4(%esp)
c0108bcb:	00 
c0108bcc:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108bd3:	e8 63 81 ff ff       	call   c0100d3b <__panic>
    for (i =4; i>=0; i--) {
c0108bd8:	ff 4d f4             	decl   -0xc(%ebp)
c0108bdb:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0108bdf:	79 8b                	jns    c0108b6c <check_vma_struct+0x403>
    }

    mm_destroy(mm);// 销毁 mm 结构
c0108be1:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108be4:	89 04 24             	mov    %eax,(%esp)
c0108be7:	e8 32 f7 ff ff       	call   c010831e <mm_destroy>

    // 确保释放的页面数量与初始记录一致
    // assert(nr_free_pages_store == nr_free_pages());
    // 输出成功信息
    cprintf("check_vma_struct() succeeded!\n");
c0108bec:	c7 04 24 1c dd 10 c0 	movl   $0xc010dd1c,(%esp)
c0108bf3:	e8 80 77 ff ff       	call   c0100378 <cprintf>
}
c0108bf8:	90                   	nop
c0108bf9:	89 ec                	mov    %ebp,%esp
c0108bfb:	5d                   	pop    %ebp
c0108bfc:	c3                   	ret    

c0108bfd <check_pgfault>:
struct mm_struct *check_mm_struct;

// check_pgfault - check correctness of pgfault handler
// 检查页故障处理的正确性
static void
check_pgfault(void) {
c0108bfd:	55                   	push   %ebp
c0108bfe:	89 e5                	mov    %esp,%ebp
c0108c00:	83 ec 38             	sub    $0x38,%esp
    // 保存当前空闲页面的数量，用于后续检查
    size_t nr_free_pages_store = nr_free_pages();
c0108c03:	e8 1b c6 ff ff       	call   c0105223 <nr_free_pages>
c0108c08:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 创建内存管理结构体
    check_mm_struct = mm_create();
c0108c0b:	e8 a5 f3 ff ff       	call   c0107fb5 <mm_create>
c0108c10:	a3 0c 41 1a c0       	mov    %eax,0xc01a410c
    // 确保内存管理结构体创建成功
    assert(check_mm_struct != NULL);
c0108c15:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c0108c1a:	85 c0                	test   %eax,%eax
c0108c1c:	75 24                	jne    c0108c42 <check_pgfault+0x45>
c0108c1e:	c7 44 24 0c 3b dd 10 	movl   $0xc010dd3b,0xc(%esp)
c0108c25:	c0 
c0108c26:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108c2d:	c0 
c0108c2e:	c7 44 24 04 c2 01 00 	movl   $0x1c2,0x4(%esp)
c0108c35:	00 
c0108c36:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108c3d:	e8 f9 80 ff ff       	call   c0100d3b <__panic>
    // 将新创建的内存管理结构体赋值给局部变量mm
    struct mm_struct *mm = check_mm_struct;
c0108c42:	a1 0c 41 1a c0       	mov    0xc01a410c,%eax
c0108c47:	89 45 e8             	mov    %eax,-0x18(%ebp)
    // 将引导程序的页目录复制到新创建的内存管理结构体中
    pde_t *pgdir = mm->pgdir = boot_pgdir;
c0108c4a:	8b 15 00 fa 12 c0    	mov    0xc012fa00,%edx
c0108c50:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108c53:	89 50 0c             	mov    %edx,0xc(%eax)
c0108c56:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108c59:	8b 40 0c             	mov    0xc(%eax),%eax
c0108c5c:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    // 确保页目录的第0项是空的
    assert(pgdir[0] == 0);
c0108c5f:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108c62:	8b 00                	mov    (%eax),%eax
c0108c64:	85 c0                	test   %eax,%eax
c0108c66:	74 24                	je     c0108c8c <check_pgfault+0x8f>
c0108c68:	c7 44 24 0c 53 dd 10 	movl   $0xc010dd53,0xc(%esp)
c0108c6f:	c0 
c0108c70:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108c77:	c0 
c0108c78:	c7 44 24 04 c8 01 00 	movl   $0x1c8,0x4(%esp)
c0108c7f:	00 
c0108c80:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108c87:	e8 af 80 ff ff       	call   c0100d3b <__panic>
    // 创建一个虚拟内存区域结构体，具有写权限
    struct vma_struct *vma = vma_create(0, PTSIZE, VM_WRITE);
c0108c8c:	c7 44 24 08 02 00 00 	movl   $0x2,0x8(%esp)
c0108c93:	00 
c0108c94:	c7 44 24 04 00 00 40 	movl   $0x400000,0x4(%esp)
c0108c9b:	00 
c0108c9c:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0108ca3:	e8 a9 f3 ff ff       	call   c0108051 <vma_create>
c0108ca8:	89 45 e0             	mov    %eax,-0x20(%ebp)
    // 确保虚拟内存区域结构体创建成功
    assert(vma != NULL);
c0108cab:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c0108caf:	75 24                	jne    c0108cd5 <check_pgfault+0xd8>
c0108cb1:	c7 44 24 0c e4 db 10 	movl   $0xc010dbe4,0xc(%esp)
c0108cb8:	c0 
c0108cb9:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108cc0:	c0 
c0108cc1:	c7 44 24 04 cc 01 00 	movl   $0x1cc,0x4(%esp)
c0108cc8:	00 
c0108cc9:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108cd0:	e8 66 80 ff ff       	call   c0100d3b <__panic>
    // 将虚拟内存区域结构体插入到内存管理结构体中
    insert_vma_struct(mm, vma);
c0108cd5:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108cd8:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108cdc:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108cdf:	89 04 24             	mov    %eax,(%esp)
c0108ce2:	e8 01 f5 ff ff       	call   c01081e8 <insert_vma_struct>
    // 定义一个地址，用于访问虚拟内存
    uintptr_t addr = 0x100;
c0108ce7:	c7 45 dc 00 01 00 00 	movl   $0x100,-0x24(%ebp)
    // 确保通过该地址可以找到之前插入的虚拟内存区域
    assert(find_vma(mm, addr) == vma);
c0108cee:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108cf1:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108cf5:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108cf8:	89 04 24             	mov    %eax,(%esp)
c0108cfb:	e8 8e f3 ff ff       	call   c010808e <find_vma>
c0108d00:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c0108d03:	74 24                	je     c0108d29 <check_pgfault+0x12c>
c0108d05:	c7 44 24 0c 61 dd 10 	movl   $0xc010dd61,0xc(%esp)
c0108d0c:	c0 
c0108d0d:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108d14:	c0 
c0108d15:	c7 44 24 04 d2 01 00 	movl   $0x1d2,0x4(%esp)
c0108d1c:	00 
c0108d1d:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108d24:	e8 12 80 ff ff       	call   c0100d3b <__panic>
    // 初始化一个累加器，用于校验写入的数据
    int i, sum = 0;
c0108d29:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    // 写入数据到虚拟内存，并累加
    for (i = 0; i < 100; i ++) {
c0108d30:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0108d37:	eb 16                	jmp    c0108d4f <check_pgfault+0x152>
        *(char *)(addr + i) = i;
c0108d39:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108d3c:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108d3f:	01 d0                	add    %edx,%eax
c0108d41:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108d44:	88 10                	mov    %dl,(%eax)
        sum += i;
c0108d46:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108d49:	01 45 f0             	add    %eax,-0x10(%ebp)
    for (i = 0; i < 100; i ++) {
c0108d4c:	ff 45 f4             	incl   -0xc(%ebp)
c0108d4f:	83 7d f4 63          	cmpl   $0x63,-0xc(%ebp)
c0108d53:	7e e4                	jle    c0108d39 <check_pgfault+0x13c>
    }
    // 读取虚拟内存中的数据，并减去，最终结果应为0
    for (i = 0; i < 100; i ++) {
c0108d55:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0108d5c:	eb 14                	jmp    c0108d72 <check_pgfault+0x175>
        sum -= *(char *)(addr + i);
c0108d5e:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108d61:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108d64:	01 d0                	add    %edx,%eax
c0108d66:	0f b6 00             	movzbl (%eax),%eax
c0108d69:	0f be c0             	movsbl %al,%eax
c0108d6c:	29 45 f0             	sub    %eax,-0x10(%ebp)
    for (i = 0; i < 100; i ++) {
c0108d6f:	ff 45 f4             	incl   -0xc(%ebp)
c0108d72:	83 7d f4 63          	cmpl   $0x63,-0xc(%ebp)
c0108d76:	7e e6                	jle    c0108d5e <check_pgfault+0x161>
    }
    // 确保累加器的值为0，证明数据读写正确
    assert(sum == 0);
c0108d78:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0108d7c:	74 24                	je     c0108da2 <check_pgfault+0x1a5>
c0108d7e:	c7 44 24 0c 7b dd 10 	movl   $0xc010dd7b,0xc(%esp)
c0108d85:	c0 
c0108d86:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108d8d:	c0 
c0108d8e:	c7 44 24 04 df 01 00 	movl   $0x1df,0x4(%esp)
c0108d95:	00 
c0108d96:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108d9d:	e8 99 7f ff ff       	call   c0100d3b <__panic>
    // 移除页目录中的相应页面
    page_remove(pgdir, ROUNDDOWN(addr, PGSIZE));
c0108da2:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108da5:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0108da8:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0108dab:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0108db0:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108db4:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108db7:	89 04 24             	mov    %eax,(%esp)
c0108dba:	e8 9d d0 ff ff       	call   c0105e5c <page_remove>
    // 释放第0项页目录对应的页面
    free_page(pde2page(pgdir[0]));
c0108dbf:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108dc2:	8b 00                	mov    (%eax),%eax
c0108dc4:	89 04 24             	mov    %eax,(%esp)
c0108dc7:	e8 cf f1 ff ff       	call   c0107f9b <pde2page>
c0108dcc:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0108dd3:	00 
c0108dd4:	89 04 24             	mov    %eax,(%esp)
c0108dd7:	e8 12 c4 ff ff       	call   c01051ee <free_pages>
    // 将页目录的第0项设置为空
    pgdir[0] = 0;
c0108ddc:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108ddf:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
    // 将内存管理结构体中的页目录设置为空
    mm->pgdir = NULL;
c0108de5:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108de8:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
    // 销毁内存管理结构体
    mm_destroy(mm);
c0108def:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108df2:	89 04 24             	mov    %eax,(%esp)
c0108df5:	e8 24 f5 ff ff       	call   c010831e <mm_destroy>
    // 将检查用的内存管理结构体设置为空
    check_mm_struct = NULL;
c0108dfa:	c7 05 0c 41 1a c0 00 	movl   $0x0,0xc01a410c
c0108e01:	00 00 00 
    // 确保空闲页面的数量没有变化，证明内存管理正确
    assert(nr_free_pages_store == nr_free_pages());
c0108e04:	e8 1a c4 ff ff       	call   c0105223 <nr_free_pages>
c0108e09:	39 45 ec             	cmp    %eax,-0x14(%ebp)
c0108e0c:	74 24                	je     c0108e32 <check_pgfault+0x235>
c0108e0e:	c7 44 24 0c 84 dd 10 	movl   $0xc010dd84,0xc(%esp)
c0108e15:	c0 
c0108e16:	c7 44 24 08 07 db 10 	movl   $0xc010db07,0x8(%esp)
c0108e1d:	c0 
c0108e1e:	c7 44 24 04 ed 01 00 	movl   $0x1ed,0x4(%esp)
c0108e25:	00 
c0108e26:	c7 04 24 1c db 10 c0 	movl   $0xc010db1c,(%esp)
c0108e2d:	e8 09 7f ff ff       	call   c0100d3b <__panic>
    // 打印成功信息
    cprintf("check_pgfault() succeeded!\n");
c0108e32:	c7 04 24 ab dd 10 c0 	movl   $0xc010ddab,(%esp)
c0108e39:	e8 3a 75 ff ff       	call   c0100378 <cprintf>
}
c0108e3e:	90                   	nop
c0108e3f:	89 ec                	mov    %ebp,%esp
c0108e41:	5d                   	pop    %ebp
c0108e42:	c3                   	ret    

c0108e43 <do_pgfault>:
 * @param addr 引发页面错误的线性地址。
 * 
 * @return 成功返回0，失败返回负错误码。
 */
int
do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
c0108e43:	55                   	push   %ebp
c0108e44:	89 e5                	mov    %esp,%ebp
c0108e46:	83 ec 38             	sub    $0x38,%esp
    int ret = -E_INVAL;// 初始化返回值为无效错误
c0108e49:	c7 45 f4 fd ff ff ff 	movl   $0xfffffffd,-0xc(%ebp)
    //try to find a vma which include addr
    // 尝试找到包含 addr 的 vma
    struct vma_struct *vma = find_vma(mm, addr);
c0108e50:	8b 45 10             	mov    0x10(%ebp),%eax
c0108e53:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108e57:	8b 45 08             	mov    0x8(%ebp),%eax
c0108e5a:	89 04 24             	mov    %eax,(%esp)
c0108e5d:	e8 2c f2 ff ff       	call   c010808e <find_vma>
c0108e62:	89 45 ec             	mov    %eax,-0x14(%ebp)

    pgfault_num++;// 增加页面错误计数
c0108e65:	a1 10 41 1a c0       	mov    0xc01a4110,%eax
c0108e6a:	40                   	inc    %eax
c0108e6b:	a3 10 41 1a c0       	mov    %eax,0xc01a4110
    // 检查 addr 是否在 mm 的 vma 范围内
    //If the addr is in the range of a mm's vma?
    if (vma == NULL || vma->vm_start > addr) {
c0108e70:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0108e74:	74 0b                	je     c0108e81 <do_pgfault+0x3e>
c0108e76:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108e79:	8b 40 04             	mov    0x4(%eax),%eax
c0108e7c:	39 45 10             	cmp    %eax,0x10(%ebp)
c0108e7f:	73 18                	jae    c0108e99 <do_pgfault+0x56>
        cprintf("not valid addr %x, and  can not find it in vma\n", addr);
c0108e81:	8b 45 10             	mov    0x10(%ebp),%eax
c0108e84:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108e88:	c7 04 24 c8 dd 10 c0 	movl   $0xc010ddc8,(%esp)
c0108e8f:	e8 e4 74 ff ff       	call   c0100378 <cprintf>
        goto failed;// 跳转到错误处理部分
c0108e94:	e9 ba 01 00 00       	jmp    c0109053 <do_pgfault+0x210>
    }
    //check the error_code
    // 检查错误代码
    switch (error_code & 3) {
c0108e99:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108e9c:	83 e0 03             	and    $0x3,%eax
c0108e9f:	85 c0                	test   %eax,%eax
c0108ea1:	74 34                	je     c0108ed7 <do_pgfault+0x94>
c0108ea3:	83 f8 01             	cmp    $0x1,%eax
c0108ea6:	74 1e                	je     c0108ec6 <do_pgfault+0x83>
    default:
            /* 默认错误代码标志：3 (W/R=1, P=1): 写操作，存在 */
            /* error code flag : default is 3 ( W/R=1, P=1): write, present */
    case 2: /* error code flag : (W/R=1, P=0): write, not present */
            /* 错误代码标志：(W/R=1, P=0): 写操作，不存在 */
        if (!(vma->vm_flags & VM_WRITE)) {
c0108ea8:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108eab:	8b 40 0c             	mov    0xc(%eax),%eax
c0108eae:	83 e0 02             	and    $0x2,%eax
c0108eb1:	85 c0                	test   %eax,%eax
c0108eb3:	75 40                	jne    c0108ef5 <do_pgfault+0xb2>
            cprintf("do_pgfault failed: error code flag = write AND not present, but the addr's vma cannot write\n");
c0108eb5:	c7 04 24 f8 dd 10 c0 	movl   $0xc010ddf8,(%esp)
c0108ebc:	e8 b7 74 ff ff       	call   c0100378 <cprintf>
            goto failed;// 跳转到错误处理部分
c0108ec1:	e9 8d 01 00 00       	jmp    c0109053 <do_pgfault+0x210>
        }
        break;
    case 1: /* error code flag : (W/R=0, P=1): read, present */
            /* 错误代码标志：(W/R=0, P=1): 读操作，存在 */
        cprintf("do_pgfault failed: error code flag = read AND present\n");
c0108ec6:	c7 04 24 58 de 10 c0 	movl   $0xc010de58,(%esp)
c0108ecd:	e8 a6 74 ff ff       	call   c0100378 <cprintf>
        goto failed;// 跳转到错误处理部分
c0108ed2:	e9 7c 01 00 00       	jmp    c0109053 <do_pgfault+0x210>
    case 0: /* error code flag : (W/R=0, P=0): read, not present */
             /* 错误代码标志：(W/R=0, P=0): 读操作，不存在 */
        if (!(vma->vm_flags & (VM_READ | VM_EXEC))) {
c0108ed7:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108eda:	8b 40 0c             	mov    0xc(%eax),%eax
c0108edd:	83 e0 05             	and    $0x5,%eax
c0108ee0:	85 c0                	test   %eax,%eax
c0108ee2:	75 12                	jne    c0108ef6 <do_pgfault+0xb3>
            cprintf("do_pgfault failed: error code flag = read AND not present, but the addr's vma cannot read or exec\n");
c0108ee4:	c7 04 24 90 de 10 c0 	movl   $0xc010de90,(%esp)
c0108eeb:	e8 88 74 ff ff       	call   c0100378 <cprintf>
            goto failed;// 跳转到错误处理部分
c0108ef0:	e9 5e 01 00 00       	jmp    c0109053 <do_pgfault+0x210>
        break;
c0108ef5:	90                   	nop
    /* 如果 (写入已存在的地址) 或
     *    (写入不存在的地址且地址可写) 或
     *    (读取不存在的地址且地址可读)
     * 则继续处理
     */
    uint32_t perm = PTE_U;// 初始化权限标志为用户可访问
c0108ef6:	c7 45 f0 04 00 00 00 	movl   $0x4,-0x10(%ebp)
    if (vma->vm_flags & VM_WRITE) {
c0108efd:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108f00:	8b 40 0c             	mov    0xc(%eax),%eax
c0108f03:	83 e0 02             	and    $0x2,%eax
c0108f06:	85 c0                	test   %eax,%eax
c0108f08:	74 04                	je     c0108f0e <do_pgfault+0xcb>
        perm |= PTE_W;// 如果 vma 可写，则设置写权限
c0108f0a:	83 4d f0 02          	orl    $0x2,-0x10(%ebp)
    }
    addr = ROUNDDOWN(addr, PGSIZE);// 将地址对齐到页边界
c0108f0e:	8b 45 10             	mov    0x10(%ebp),%eax
c0108f11:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0108f14:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108f17:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0108f1c:	89 45 10             	mov    %eax,0x10(%ebp)

    ret = -E_NO_MEM;// 初始化返回值为内存不足错误
c0108f1f:	c7 45 f4 fc ff ff ff 	movl   $0xfffffffc,-0xc(%ebp)

    pte_t *ptep=NULL;
c0108f26:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
#endif
    // try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT.
    // (notice the 3th parameter '1')
    // 尝试找到一个页表项 pte，如果包含该 pte 的页表不存在，则创建一个页表。
    // 注意第三个参数 '1' 表示如果需要，可以创建新的页表。
    if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) {
c0108f2d:	8b 45 08             	mov    0x8(%ebp),%eax
c0108f30:	8b 40 0c             	mov    0xc(%eax),%eax
c0108f33:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c0108f3a:	00 
c0108f3b:	8b 55 10             	mov    0x10(%ebp),%edx
c0108f3e:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108f42:	89 04 24             	mov    %eax,(%esp)
c0108f45:	e8 f2 c8 ff ff       	call   c010583c <get_pte>
c0108f4a:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0108f4d:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0108f51:	75 11                	jne    c0108f64 <do_pgfault+0x121>
        cprintf("get_pte in do_pgfault failed\n");// 输出错误信息
c0108f53:	c7 04 24 f3 de 10 c0 	movl   $0xc010def3,(%esp)
c0108f5a:	e8 19 74 ff ff       	call   c0100378 <cprintf>
        goto failed;// 跳转到错误处理部分
c0108f5f:	e9 ef 00 00 00       	jmp    c0109053 <do_pgfault+0x210>
    }
    // 如果页表项 pte 的物理地址不存在，则分配一页内存并映射物理地址与逻辑地址
    if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr
c0108f64:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108f67:	8b 00                	mov    (%eax),%eax
c0108f69:	85 c0                	test   %eax,%eax
c0108f6b:	75 35                	jne    c0108fa2 <do_pgfault+0x15f>
        if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) {
c0108f6d:	8b 45 08             	mov    0x8(%ebp),%eax
c0108f70:	8b 40 0c             	mov    0xc(%eax),%eax
c0108f73:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0108f76:	89 54 24 08          	mov    %edx,0x8(%esp)
c0108f7a:	8b 55 10             	mov    0x10(%ebp),%edx
c0108f7d:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108f81:	89 04 24             	mov    %eax,(%esp)
c0108f84:	e8 34 d0 ff ff       	call   c0105fbd <pgdir_alloc_page>
c0108f89:	85 c0                	test   %eax,%eax
c0108f8b:	0f 85 bb 00 00 00    	jne    c010904c <do_pgfault+0x209>
            cprintf("pgdir_alloc_page in do_pgfault failed\n");// 输出错误信息
c0108f91:	c7 04 24 14 df 10 c0 	movl   $0xc010df14,(%esp)
c0108f98:	e8 db 73 ff ff       	call   c0100378 <cprintf>
            goto failed;// 跳转到错误处理部分
c0108f9d:	e9 b1 00 00 00       	jmp    c0109053 <do_pgfault+0x210>
    }
    else { // if this pte is a swap entry, then load data from disk to a page with phy addr
           // and call page_insert to map the phy addr with logical addr
           // 如果页表项 pte 是一个交换项，则从磁盘加载数据到
           //一个具有物理地址的页面，并映射物理地址与逻辑地址
        if(swap_init_ok) {// 检查交换初始化是否成功
c0108fa2:	a1 44 40 1a c0       	mov    0xc01a4044,%eax
c0108fa7:	85 c0                	test   %eax,%eax
c0108fa9:	0f 84 86 00 00 00    	je     c0109035 <do_pgfault+0x1f2>
            struct Page *page=NULL;// 声明一个页面指针
c0108faf:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
            if ((ret = swap_in(mm, addr, &page)) != 0) {
c0108fb6:	8d 45 e0             	lea    -0x20(%ebp),%eax
c0108fb9:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108fbd:	8b 45 10             	mov    0x10(%ebp),%eax
c0108fc0:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108fc4:	8b 45 08             	mov    0x8(%ebp),%eax
c0108fc7:	89 04 24             	mov    %eax,(%esp)
c0108fca:	e8 c6 e0 ff ff       	call   c0107095 <swap_in>
c0108fcf:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108fd2:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0108fd6:	74 0e                	je     c0108fe6 <do_pgfault+0x1a3>
                cprintf("swap_in in do_pgfault failed\n");
c0108fd8:	c7 04 24 3b df 10 c0 	movl   $0xc010df3b,(%esp)
c0108fdf:	e8 94 73 ff ff       	call   c0100378 <cprintf>
c0108fe4:	eb 6d                	jmp    c0109053 <do_pgfault+0x210>
                goto failed;
            }    
            page_insert(mm->pgdir, page, addr, perm);// 设置物理地址与逻辑地址的映射
c0108fe6:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0108fe9:	8b 45 08             	mov    0x8(%ebp),%eax
c0108fec:	8b 40 0c             	mov    0xc(%eax),%eax
c0108fef:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c0108ff2:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c0108ff6:	8b 4d 10             	mov    0x10(%ebp),%ecx
c0108ff9:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0108ffd:	89 54 24 04          	mov    %edx,0x4(%esp)
c0109001:	89 04 24             	mov    %eax,(%esp)
c0109004:	e8 9a ce ff ff       	call   c0105ea3 <page_insert>
            swap_map_swappable(mm, addr, page, 1);// 设置页面可交换
c0109009:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010900c:	c7 44 24 0c 01 00 00 	movl   $0x1,0xc(%esp)
c0109013:	00 
c0109014:	89 44 24 08          	mov    %eax,0x8(%esp)
c0109018:	8b 45 10             	mov    0x10(%ebp),%eax
c010901b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010901f:	8b 45 08             	mov    0x8(%ebp),%eax
c0109022:	89 04 24             	mov    %eax,(%esp)
c0109025:	e8 a3 de ff ff       	call   c0106ecd <swap_map_swappable>
            page->pra_vaddr = addr;// 记录页面的虚拟地址
c010902a:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010902d:	8b 55 10             	mov    0x10(%ebp),%edx
c0109030:	89 50 1c             	mov    %edx,0x1c(%eax)
c0109033:	eb 17                	jmp    c010904c <do_pgfault+0x209>
        }
        else {
            cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep);
c0109035:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0109038:	8b 00                	mov    (%eax),%eax
c010903a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010903e:	c7 04 24 5c df 10 c0 	movl   $0xc010df5c,(%esp)
c0109045:	e8 2e 73 ff ff       	call   c0100378 <cprintf>
            goto failed;// 跳转到错误处理部分
c010904a:	eb 07                	jmp    c0109053 <do_pgfault+0x210>
        }
   }
   ret = 0;
c010904c:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
failed:
    return ret;
c0109053:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0109056:	89 ec                	mov    %ebp,%esp
c0109058:	5d                   	pop    %ebp
c0109059:	c3                   	ret    

c010905a <user_mem_check>:

bool
user_mem_check(struct mm_struct *mm, uintptr_t addr, size_t len, bool write) {
c010905a:	55                   	push   %ebp
c010905b:	89 e5                	mov    %esp,%ebp
c010905d:	83 ec 18             	sub    $0x18,%esp
    if (mm != NULL) {
c0109060:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0109064:	0f 84 e0 00 00 00    	je     c010914a <user_mem_check+0xf0>
        if (!USER_ACCESS(addr, addr + len)) {
c010906a:	81 7d 0c ff ff 1f 00 	cmpl   $0x1fffff,0xc(%ebp)
c0109071:	76 1c                	jbe    c010908f <user_mem_check+0x35>
c0109073:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109076:	8b 45 10             	mov    0x10(%ebp),%eax
c0109079:	01 d0                	add    %edx,%eax
c010907b:	39 45 0c             	cmp    %eax,0xc(%ebp)
c010907e:	73 0f                	jae    c010908f <user_mem_check+0x35>
c0109080:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109083:	8b 45 10             	mov    0x10(%ebp),%eax
c0109086:	01 d0                	add    %edx,%eax
c0109088:	3d 00 00 00 b0       	cmp    $0xb0000000,%eax
c010908d:	76 0a                	jbe    c0109099 <user_mem_check+0x3f>
            return 0;
c010908f:	b8 00 00 00 00       	mov    $0x0,%eax
c0109094:	e9 e2 00 00 00       	jmp    c010917b <user_mem_check+0x121>
        }
        struct vma_struct *vma;
        uintptr_t start = addr, end = addr + len;
c0109099:	8b 45 0c             	mov    0xc(%ebp),%eax
c010909c:	89 45 fc             	mov    %eax,-0x4(%ebp)
c010909f:	8b 55 0c             	mov    0xc(%ebp),%edx
c01090a2:	8b 45 10             	mov    0x10(%ebp),%eax
c01090a5:	01 d0                	add    %edx,%eax
c01090a7:	89 45 f8             	mov    %eax,-0x8(%ebp)
        while (start < end) {
c01090aa:	e9 88 00 00 00       	jmp    c0109137 <user_mem_check+0xdd>
            if ((vma = find_vma(mm, start)) == NULL || start < vma->vm_start) {
c01090af:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01090b2:	89 44 24 04          	mov    %eax,0x4(%esp)
c01090b6:	8b 45 08             	mov    0x8(%ebp),%eax
c01090b9:	89 04 24             	mov    %eax,(%esp)
c01090bc:	e8 cd ef ff ff       	call   c010808e <find_vma>
c01090c1:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01090c4:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01090c8:	74 0b                	je     c01090d5 <user_mem_check+0x7b>
c01090ca:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01090cd:	8b 40 04             	mov    0x4(%eax),%eax
c01090d0:	39 45 fc             	cmp    %eax,-0x4(%ebp)
c01090d3:	73 0a                	jae    c01090df <user_mem_check+0x85>
                return 0;
c01090d5:	b8 00 00 00 00       	mov    $0x0,%eax
c01090da:	e9 9c 00 00 00       	jmp    c010917b <user_mem_check+0x121>
            }
            if (!(vma->vm_flags & ((write) ? VM_WRITE : VM_READ))) {
c01090df:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01090e2:	8b 40 0c             	mov    0xc(%eax),%eax
c01090e5:	83 7d 14 00          	cmpl   $0x0,0x14(%ebp)
c01090e9:	74 07                	je     c01090f2 <user_mem_check+0x98>
c01090eb:	ba 02 00 00 00       	mov    $0x2,%edx
c01090f0:	eb 05                	jmp    c01090f7 <user_mem_check+0x9d>
c01090f2:	ba 01 00 00 00       	mov    $0x1,%edx
c01090f7:	21 d0                	and    %edx,%eax
c01090f9:	85 c0                	test   %eax,%eax
c01090fb:	75 07                	jne    c0109104 <user_mem_check+0xaa>
                return 0;
c01090fd:	b8 00 00 00 00       	mov    $0x0,%eax
c0109102:	eb 77                	jmp    c010917b <user_mem_check+0x121>
            }
            if (write && (vma->vm_flags & VM_STACK)) {
c0109104:	83 7d 14 00          	cmpl   $0x0,0x14(%ebp)
c0109108:	74 24                	je     c010912e <user_mem_check+0xd4>
c010910a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010910d:	8b 40 0c             	mov    0xc(%eax),%eax
c0109110:	83 e0 08             	and    $0x8,%eax
c0109113:	85 c0                	test   %eax,%eax
c0109115:	74 17                	je     c010912e <user_mem_check+0xd4>
                if (start < vma->vm_start + PGSIZE) { //check stack start & size
c0109117:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010911a:	8b 40 04             	mov    0x4(%eax),%eax
c010911d:	05 00 10 00 00       	add    $0x1000,%eax
c0109122:	39 45 fc             	cmp    %eax,-0x4(%ebp)
c0109125:	73 07                	jae    c010912e <user_mem_check+0xd4>
                    return 0;
c0109127:	b8 00 00 00 00       	mov    $0x0,%eax
c010912c:	eb 4d                	jmp    c010917b <user_mem_check+0x121>
                }
            }
            start = vma->vm_end;
c010912e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109131:	8b 40 08             	mov    0x8(%eax),%eax
c0109134:	89 45 fc             	mov    %eax,-0x4(%ebp)
        while (start < end) {
c0109137:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010913a:	3b 45 f8             	cmp    -0x8(%ebp),%eax
c010913d:	0f 82 6c ff ff ff    	jb     c01090af <user_mem_check+0x55>
        }
        return 1;
c0109143:	b8 01 00 00 00       	mov    $0x1,%eax
c0109148:	eb 31                	jmp    c010917b <user_mem_check+0x121>
    }
    return KERN_ACCESS(addr, addr + len);
c010914a:	81 7d 0c ff ff ff bf 	cmpl   $0xbfffffff,0xc(%ebp)
c0109151:	76 23                	jbe    c0109176 <user_mem_check+0x11c>
c0109153:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109156:	8b 45 10             	mov    0x10(%ebp),%eax
c0109159:	01 d0                	add    %edx,%eax
c010915b:	39 45 0c             	cmp    %eax,0xc(%ebp)
c010915e:	73 16                	jae    c0109176 <user_mem_check+0x11c>
c0109160:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109163:	8b 45 10             	mov    0x10(%ebp),%eax
c0109166:	01 d0                	add    %edx,%eax
c0109168:	3d 00 00 00 f8       	cmp    $0xf8000000,%eax
c010916d:	77 07                	ja     c0109176 <user_mem_check+0x11c>
c010916f:	b8 01 00 00 00       	mov    $0x1,%eax
c0109174:	eb 05                	jmp    c010917b <user_mem_check+0x121>
c0109176:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010917b:	89 ec                	mov    %ebp,%esp
c010917d:	5d                   	pop    %ebp
c010917e:	c3                   	ret    

c010917f <page2ppn>:
page2ppn(struct Page *page) {
c010917f:	55                   	push   %ebp
c0109180:	89 e5                	mov    %esp,%ebp
    return page - pages;
c0109182:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c0109188:	8b 45 08             	mov    0x8(%ebp),%eax
c010918b:	29 d0                	sub    %edx,%eax
c010918d:	c1 f8 05             	sar    $0x5,%eax
}
c0109190:	5d                   	pop    %ebp
c0109191:	c3                   	ret    

c0109192 <page2pa>:
page2pa(struct Page *page) {
c0109192:	55                   	push   %ebp
c0109193:	89 e5                	mov    %esp,%ebp
c0109195:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0109198:	8b 45 08             	mov    0x8(%ebp),%eax
c010919b:	89 04 24             	mov    %eax,(%esp)
c010919e:	e8 dc ff ff ff       	call   c010917f <page2ppn>
c01091a3:	c1 e0 0c             	shl    $0xc,%eax
}
c01091a6:	89 ec                	mov    %ebp,%esp
c01091a8:	5d                   	pop    %ebp
c01091a9:	c3                   	ret    

c01091aa <page2kva>:
page2kva(struct Page *page) {
c01091aa:	55                   	push   %ebp
c01091ab:	89 e5                	mov    %esp,%ebp
c01091ad:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c01091b0:	8b 45 08             	mov    0x8(%ebp),%eax
c01091b3:	89 04 24             	mov    %eax,(%esp)
c01091b6:	e8 d7 ff ff ff       	call   c0109192 <page2pa>
c01091bb:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01091be:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01091c1:	c1 e8 0c             	shr    $0xc,%eax
c01091c4:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01091c7:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c01091cc:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01091cf:	72 23                	jb     c01091f4 <page2kva+0x4a>
c01091d1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01091d4:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01091d8:	c7 44 24 08 84 df 10 	movl   $0xc010df84,0x8(%esp)
c01091df:	c0 
c01091e0:	c7 44 24 04 65 00 00 	movl   $0x65,0x4(%esp)
c01091e7:	00 
c01091e8:	c7 04 24 a7 df 10 c0 	movl   $0xc010dfa7,(%esp)
c01091ef:	e8 47 7b ff ff       	call   c0100d3b <__panic>
c01091f4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01091f7:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c01091fc:	89 ec                	mov    %ebp,%esp
c01091fe:	5d                   	pop    %ebp
c01091ff:	c3                   	ret    

c0109200 <swapfs_init>:
#include <ide.h>
#include <pmm.h>
#include <assert.h>

void
swapfs_init(void) {
c0109200:	55                   	push   %ebp
c0109201:	89 e5                	mov    %esp,%ebp
c0109203:	83 ec 18             	sub    $0x18,%esp
    static_assert((PGSIZE % SECTSIZE) == 0);
    if (!ide_device_valid(SWAP_DEV_NO)) {
c0109206:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c010920d:	e8 d8 88 ff ff       	call   c0101aea <ide_device_valid>
c0109212:	85 c0                	test   %eax,%eax
c0109214:	75 1c                	jne    c0109232 <swapfs_init+0x32>
        panic("swap fs isn't available.\n");
c0109216:	c7 44 24 08 b5 df 10 	movl   $0xc010dfb5,0x8(%esp)
c010921d:	c0 
c010921e:	c7 44 24 04 0d 00 00 	movl   $0xd,0x4(%esp)
c0109225:	00 
c0109226:	c7 04 24 cf df 10 c0 	movl   $0xc010dfcf,(%esp)
c010922d:	e8 09 7b ff ff       	call   c0100d3b <__panic>
    }
    max_swap_offset = ide_device_size(SWAP_DEV_NO) / (PGSIZE / SECTSIZE);
c0109232:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0109239:	e8 ec 88 ff ff       	call   c0101b2a <ide_device_size>
c010923e:	c1 e8 03             	shr    $0x3,%eax
c0109241:	a3 40 40 1a c0       	mov    %eax,0xc01a4040
}
c0109246:	90                   	nop
c0109247:	89 ec                	mov    %ebp,%esp
c0109249:	5d                   	pop    %ebp
c010924a:	c3                   	ret    

c010924b <swapfs_read>:

int
swapfs_read(swap_entry_t entry, struct Page *page) {
c010924b:	55                   	push   %ebp
c010924c:	89 e5                	mov    %esp,%ebp
c010924e:	83 ec 28             	sub    $0x28,%esp
    return ide_read_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT);
c0109251:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109254:	89 04 24             	mov    %eax,(%esp)
c0109257:	e8 4e ff ff ff       	call   c01091aa <page2kva>
c010925c:	8b 55 08             	mov    0x8(%ebp),%edx
c010925f:	c1 ea 08             	shr    $0x8,%edx
c0109262:	89 55 f4             	mov    %edx,-0xc(%ebp)
c0109265:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0109269:	74 0b                	je     c0109276 <swapfs_read+0x2b>
c010926b:	8b 15 40 40 1a c0    	mov    0xc01a4040,%edx
c0109271:	39 55 f4             	cmp    %edx,-0xc(%ebp)
c0109274:	72 23                	jb     c0109299 <swapfs_read+0x4e>
c0109276:	8b 45 08             	mov    0x8(%ebp),%eax
c0109279:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010927d:	c7 44 24 08 e0 df 10 	movl   $0xc010dfe0,0x8(%esp)
c0109284:	c0 
c0109285:	c7 44 24 04 14 00 00 	movl   $0x14,0x4(%esp)
c010928c:	00 
c010928d:	c7 04 24 cf df 10 c0 	movl   $0xc010dfcf,(%esp)
c0109294:	e8 a2 7a ff ff       	call   c0100d3b <__panic>
c0109299:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010929c:	c1 e2 03             	shl    $0x3,%edx
c010929f:	c7 44 24 0c 08 00 00 	movl   $0x8,0xc(%esp)
c01092a6:	00 
c01092a7:	89 44 24 08          	mov    %eax,0x8(%esp)
c01092ab:	89 54 24 04          	mov    %edx,0x4(%esp)
c01092af:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01092b6:	e8 ac 88 ff ff       	call   c0101b67 <ide_read_secs>
}
c01092bb:	89 ec                	mov    %ebp,%esp
c01092bd:	5d                   	pop    %ebp
c01092be:	c3                   	ret    

c01092bf <swapfs_write>:

int
swapfs_write(swap_entry_t entry, struct Page *page) {
c01092bf:	55                   	push   %ebp
c01092c0:	89 e5                	mov    %esp,%ebp
c01092c2:	83 ec 28             	sub    $0x28,%esp
    return ide_write_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT);
c01092c5:	8b 45 0c             	mov    0xc(%ebp),%eax
c01092c8:	89 04 24             	mov    %eax,(%esp)
c01092cb:	e8 da fe ff ff       	call   c01091aa <page2kva>
c01092d0:	8b 55 08             	mov    0x8(%ebp),%edx
c01092d3:	c1 ea 08             	shr    $0x8,%edx
c01092d6:	89 55 f4             	mov    %edx,-0xc(%ebp)
c01092d9:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01092dd:	74 0b                	je     c01092ea <swapfs_write+0x2b>
c01092df:	8b 15 40 40 1a c0    	mov    0xc01a4040,%edx
c01092e5:	39 55 f4             	cmp    %edx,-0xc(%ebp)
c01092e8:	72 23                	jb     c010930d <swapfs_write+0x4e>
c01092ea:	8b 45 08             	mov    0x8(%ebp),%eax
c01092ed:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01092f1:	c7 44 24 08 e0 df 10 	movl   $0xc010dfe0,0x8(%esp)
c01092f8:	c0 
c01092f9:	c7 44 24 04 19 00 00 	movl   $0x19,0x4(%esp)
c0109300:	00 
c0109301:	c7 04 24 cf df 10 c0 	movl   $0xc010dfcf,(%esp)
c0109308:	e8 2e 7a ff ff       	call   c0100d3b <__panic>
c010930d:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0109310:	c1 e2 03             	shl    $0x3,%edx
c0109313:	c7 44 24 0c 08 00 00 	movl   $0x8,0xc(%esp)
c010931a:	00 
c010931b:	89 44 24 08          	mov    %eax,0x8(%esp)
c010931f:	89 54 24 04          	mov    %edx,0x4(%esp)
c0109323:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c010932a:	e8 79 8a ff ff       	call   c0101da8 <ide_write_secs>
}
c010932f:	89 ec                	mov    %ebp,%esp
c0109331:	5d                   	pop    %ebp
c0109332:	c3                   	ret    

c0109333 <kernel_thread_entry>:
.text
.globl kernel_thread_entry
kernel_thread_entry:        # void kernel_thread(void)

    pushl %edx              # push arg
c0109333:	52                   	push   %edx
    call *%ebx              # call fn
c0109334:	ff d3                	call   *%ebx

    pushl %eax              # save the return value of fn(arg)
c0109336:	50                   	push   %eax
    call do_exit            # call do_exit to terminate current thread
c0109337:	e8 d4 0c 00 00       	call   c010a010 <do_exit>

c010933c <test_and_set_bit>:
 * test_and_set_bit - Atomically set a bit and return its old value
 * @nr:     the bit to set
 * @addr:   the address to count from
 * */
static inline bool
test_and_set_bit(int nr, volatile void *addr) {
c010933c:	55                   	push   %ebp
c010933d:	89 e5                	mov    %esp,%ebp
c010933f:	83 ec 10             	sub    $0x10,%esp
    int oldbit;
    asm volatile ("btsl %2, %1; sbbl %0, %0" : "=r" (oldbit), "=m" (*(volatile long *)addr) : "Ir" (nr) : "memory");
c0109342:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109345:	8b 45 08             	mov    0x8(%ebp),%eax
c0109348:	0f ab 02             	bts    %eax,(%edx)
c010934b:	19 c0                	sbb    %eax,%eax
c010934d:	89 45 fc             	mov    %eax,-0x4(%ebp)
    return oldbit != 0;
c0109350:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c0109354:	0f 95 c0             	setne  %al
c0109357:	0f b6 c0             	movzbl %al,%eax
}
c010935a:	89 ec                	mov    %ebp,%esp
c010935c:	5d                   	pop    %ebp
c010935d:	c3                   	ret    

c010935e <test_and_clear_bit>:
 * test_and_clear_bit - Atomically clear a bit and return its old value
 * @nr:     the bit to clear
 * @addr:   the address to count from
 * */
static inline bool
test_and_clear_bit(int nr, volatile void *addr) {
c010935e:	55                   	push   %ebp
c010935f:	89 e5                	mov    %esp,%ebp
c0109361:	83 ec 10             	sub    $0x10,%esp
    int oldbit;
    asm volatile ("btrl %2, %1; sbbl %0, %0" : "=r" (oldbit), "=m" (*(volatile long *)addr) : "Ir" (nr) : "memory");
c0109364:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109367:	8b 45 08             	mov    0x8(%ebp),%eax
c010936a:	0f b3 02             	btr    %eax,(%edx)
c010936d:	19 c0                	sbb    %eax,%eax
c010936f:	89 45 fc             	mov    %eax,-0x4(%ebp)
    return oldbit != 0;
c0109372:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c0109376:	0f 95 c0             	setne  %al
c0109379:	0f b6 c0             	movzbl %al,%eax
}
c010937c:	89 ec                	mov    %ebp,%esp
c010937e:	5d                   	pop    %ebp
c010937f:	c3                   	ret    

c0109380 <__intr_save>:
__intr_save(void) {
c0109380:	55                   	push   %ebp
c0109381:	89 e5                	mov    %esp,%ebp
c0109383:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c0109386:	9c                   	pushf  
c0109387:	58                   	pop    %eax
c0109388:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c010938b:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c010938e:	25 00 02 00 00       	and    $0x200,%eax
c0109393:	85 c0                	test   %eax,%eax
c0109395:	74 0c                	je     c01093a3 <__intr_save+0x23>
        intr_disable();
c0109397:	e8 55 8c ff ff       	call   c0101ff1 <intr_disable>
        return 1;
c010939c:	b8 01 00 00 00       	mov    $0x1,%eax
c01093a1:	eb 05                	jmp    c01093a8 <__intr_save+0x28>
    return 0;
c01093a3:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01093a8:	89 ec                	mov    %ebp,%esp
c01093aa:	5d                   	pop    %ebp
c01093ab:	c3                   	ret    

c01093ac <__intr_restore>:
__intr_restore(bool flag) {
c01093ac:	55                   	push   %ebp
c01093ad:	89 e5                	mov    %esp,%ebp
c01093af:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c01093b2:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c01093b6:	74 05                	je     c01093bd <__intr_restore+0x11>
        intr_enable();
c01093b8:	e8 2c 8c ff ff       	call   c0101fe9 <intr_enable>
}
c01093bd:	90                   	nop
c01093be:	89 ec                	mov    %ebp,%esp
c01093c0:	5d                   	pop    %ebp
c01093c1:	c3                   	ret    

c01093c2 <try_lock>:

static inline bool
try_lock(lock_t *lock) {
c01093c2:	55                   	push   %ebp
c01093c3:	89 e5                	mov    %esp,%ebp
c01093c5:	83 ec 08             	sub    $0x8,%esp
    return !test_and_set_bit(0, lock);
c01093c8:	8b 45 08             	mov    0x8(%ebp),%eax
c01093cb:	89 44 24 04          	mov    %eax,0x4(%esp)
c01093cf:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c01093d6:	e8 61 ff ff ff       	call   c010933c <test_and_set_bit>
c01093db:	85 c0                	test   %eax,%eax
c01093dd:	0f 94 c0             	sete   %al
c01093e0:	0f b6 c0             	movzbl %al,%eax
}
c01093e3:	89 ec                	mov    %ebp,%esp
c01093e5:	5d                   	pop    %ebp
c01093e6:	c3                   	ret    

c01093e7 <lock>:

static inline void
lock(lock_t *lock) {
c01093e7:	55                   	push   %ebp
c01093e8:	89 e5                	mov    %esp,%ebp
c01093ea:	83 ec 18             	sub    $0x18,%esp
    while (!try_lock(lock)) {
c01093ed:	eb 05                	jmp    c01093f4 <lock+0xd>
        schedule();
c01093ef:	e8 88 1c 00 00       	call   c010b07c <schedule>
    while (!try_lock(lock)) {
c01093f4:	8b 45 08             	mov    0x8(%ebp),%eax
c01093f7:	89 04 24             	mov    %eax,(%esp)
c01093fa:	e8 c3 ff ff ff       	call   c01093c2 <try_lock>
c01093ff:	85 c0                	test   %eax,%eax
c0109401:	74 ec                	je     c01093ef <lock+0x8>
    }
}
c0109403:	90                   	nop
c0109404:	90                   	nop
c0109405:	89 ec                	mov    %ebp,%esp
c0109407:	5d                   	pop    %ebp
c0109408:	c3                   	ret    

c0109409 <unlock>:

static inline void
unlock(lock_t *lock) {
c0109409:	55                   	push   %ebp
c010940a:	89 e5                	mov    %esp,%ebp
c010940c:	83 ec 18             	sub    $0x18,%esp
    if (!test_and_clear_bit(0, lock)) {
c010940f:	8b 45 08             	mov    0x8(%ebp),%eax
c0109412:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109416:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c010941d:	e8 3c ff ff ff       	call   c010935e <test_and_clear_bit>
c0109422:	85 c0                	test   %eax,%eax
c0109424:	75 1c                	jne    c0109442 <unlock+0x39>
        panic("Unlock failed.\n");
c0109426:	c7 44 24 08 00 e0 10 	movl   $0xc010e000,0x8(%esp)
c010942d:	c0 
c010942e:	c7 44 24 04 34 00 00 	movl   $0x34,0x4(%esp)
c0109435:	00 
c0109436:	c7 04 24 10 e0 10 c0 	movl   $0xc010e010,(%esp)
c010943d:	e8 f9 78 ff ff       	call   c0100d3b <__panic>
    }
}
c0109442:	90                   	nop
c0109443:	89 ec                	mov    %ebp,%esp
c0109445:	5d                   	pop    %ebp
c0109446:	c3                   	ret    

c0109447 <page2ppn>:
page2ppn(struct Page *page) {
c0109447:	55                   	push   %ebp
c0109448:	89 e5                	mov    %esp,%ebp
    return page - pages;
c010944a:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c0109450:	8b 45 08             	mov    0x8(%ebp),%eax
c0109453:	29 d0                	sub    %edx,%eax
c0109455:	c1 f8 05             	sar    $0x5,%eax
}
c0109458:	5d                   	pop    %ebp
c0109459:	c3                   	ret    

c010945a <page2pa>:
page2pa(struct Page *page) {
c010945a:	55                   	push   %ebp
c010945b:	89 e5                	mov    %esp,%ebp
c010945d:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0109460:	8b 45 08             	mov    0x8(%ebp),%eax
c0109463:	89 04 24             	mov    %eax,(%esp)
c0109466:	e8 dc ff ff ff       	call   c0109447 <page2ppn>
c010946b:	c1 e0 0c             	shl    $0xc,%eax
}
c010946e:	89 ec                	mov    %ebp,%esp
c0109470:	5d                   	pop    %ebp
c0109471:	c3                   	ret    

c0109472 <pa2page>:
pa2page(uintptr_t pa) {
c0109472:	55                   	push   %ebp
c0109473:	89 e5                	mov    %esp,%ebp
c0109475:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c0109478:	8b 45 08             	mov    0x8(%ebp),%eax
c010947b:	c1 e8 0c             	shr    $0xc,%eax
c010947e:	89 c2                	mov    %eax,%edx
c0109480:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c0109485:	39 c2                	cmp    %eax,%edx
c0109487:	72 1c                	jb     c01094a5 <pa2page+0x33>
        panic("pa2page called with invalid pa");
c0109489:	c7 44 24 08 24 e0 10 	movl   $0xc010e024,0x8(%esp)
c0109490:	c0 
c0109491:	c7 44 24 04 5e 00 00 	movl   $0x5e,0x4(%esp)
c0109498:	00 
c0109499:	c7 04 24 43 e0 10 c0 	movl   $0xc010e043,(%esp)
c01094a0:	e8 96 78 ff ff       	call   c0100d3b <__panic>
    return &pages[PPN(pa)];
c01094a5:	8b 15 a0 3f 1a c0    	mov    0xc01a3fa0,%edx
c01094ab:	8b 45 08             	mov    0x8(%ebp),%eax
c01094ae:	c1 e8 0c             	shr    $0xc,%eax
c01094b1:	c1 e0 05             	shl    $0x5,%eax
c01094b4:	01 d0                	add    %edx,%eax
}
c01094b6:	89 ec                	mov    %ebp,%esp
c01094b8:	5d                   	pop    %ebp
c01094b9:	c3                   	ret    

c01094ba <page2kva>:
page2kva(struct Page *page) {
c01094ba:	55                   	push   %ebp
c01094bb:	89 e5                	mov    %esp,%ebp
c01094bd:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c01094c0:	8b 45 08             	mov    0x8(%ebp),%eax
c01094c3:	89 04 24             	mov    %eax,(%esp)
c01094c6:	e8 8f ff ff ff       	call   c010945a <page2pa>
c01094cb:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01094ce:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01094d1:	c1 e8 0c             	shr    $0xc,%eax
c01094d4:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01094d7:	a1 a4 3f 1a c0       	mov    0xc01a3fa4,%eax
c01094dc:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01094df:	72 23                	jb     c0109504 <page2kva+0x4a>
c01094e1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01094e4:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01094e8:	c7 44 24 08 54 e0 10 	movl   $0xc010e054,0x8(%esp)
c01094ef:	c0 
c01094f0:	c7 44 24 04 65 00 00 	movl   $0x65,0x4(%esp)
c01094f7:	00 
c01094f8:	c7 04 24 43 e0 10 c0 	movl   $0xc010e043,(%esp)
c01094ff:	e8 37 78 ff ff       	call   c0100d3b <__panic>
c0109504:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109507:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c010950c:	89 ec                	mov    %ebp,%esp
c010950e:	5d                   	pop    %ebp
c010950f:	c3                   	ret    

c0109510 <kva2page>:
kva2page(void *kva) {
c0109510:	55                   	push   %ebp
c0109511:	89 e5                	mov    %esp,%ebp
c0109513:	83 ec 28             	sub    $0x28,%esp
    return pa2page(PADDR(kva));
c0109516:	8b 45 08             	mov    0x8(%ebp),%eax
c0109519:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010951c:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c0109523:	77 23                	ja     c0109548 <kva2page+0x38>
c0109525:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109528:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010952c:	c7 44 24 08 78 e0 10 	movl   $0xc010e078,0x8(%esp)
c0109533:	c0 
c0109534:	c7 44 24 04 6a 00 00 	movl   $0x6a,0x4(%esp)
c010953b:	00 
c010953c:	c7 04 24 43 e0 10 c0 	movl   $0xc010e043,(%esp)
c0109543:	e8 f3 77 ff ff       	call   c0100d3b <__panic>
c0109548:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010954b:	05 00 00 00 40       	add    $0x40000000,%eax
c0109550:	89 04 24             	mov    %eax,(%esp)
c0109553:	e8 1a ff ff ff       	call   c0109472 <pa2page>
}
c0109558:	89 ec                	mov    %ebp,%esp
c010955a:	5d                   	pop    %ebp
c010955b:	c3                   	ret    

c010955c <mm_count_inc>:

static inline int
mm_count_inc(struct mm_struct *mm) {
c010955c:	55                   	push   %ebp
c010955d:	89 e5                	mov    %esp,%ebp
    mm->mm_count += 1;
c010955f:	8b 45 08             	mov    0x8(%ebp),%eax
c0109562:	8b 40 18             	mov    0x18(%eax),%eax
c0109565:	8d 50 01             	lea    0x1(%eax),%edx
c0109568:	8b 45 08             	mov    0x8(%ebp),%eax
c010956b:	89 50 18             	mov    %edx,0x18(%eax)
    return mm->mm_count;
c010956e:	8b 45 08             	mov    0x8(%ebp),%eax
c0109571:	8b 40 18             	mov    0x18(%eax),%eax
}
c0109574:	5d                   	pop    %ebp
c0109575:	c3                   	ret    

c0109576 <mm_count_dec>:

static inline int
mm_count_dec(struct mm_struct *mm) {
c0109576:	55                   	push   %ebp
c0109577:	89 e5                	mov    %esp,%ebp
    mm->mm_count -= 1;
c0109579:	8b 45 08             	mov    0x8(%ebp),%eax
c010957c:	8b 40 18             	mov    0x18(%eax),%eax
c010957f:	8d 50 ff             	lea    -0x1(%eax),%edx
c0109582:	8b 45 08             	mov    0x8(%ebp),%eax
c0109585:	89 50 18             	mov    %edx,0x18(%eax)
    return mm->mm_count;
c0109588:	8b 45 08             	mov    0x8(%ebp),%eax
c010958b:	8b 40 18             	mov    0x18(%eax),%eax
}
c010958e:	5d                   	pop    %ebp
c010958f:	c3                   	ret    

c0109590 <lock_mm>:

static inline void
lock_mm(struct mm_struct *mm) {
c0109590:	55                   	push   %ebp
c0109591:	89 e5                	mov    %esp,%ebp
c0109593:	83 ec 18             	sub    $0x18,%esp
    if (mm != NULL) {
c0109596:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c010959a:	74 0e                	je     c01095aa <lock_mm+0x1a>
        lock(&(mm->mm_lock));
c010959c:	8b 45 08             	mov    0x8(%ebp),%eax
c010959f:	83 c0 1c             	add    $0x1c,%eax
c01095a2:	89 04 24             	mov    %eax,(%esp)
c01095a5:	e8 3d fe ff ff       	call   c01093e7 <lock>
    }
}
c01095aa:	90                   	nop
c01095ab:	89 ec                	mov    %ebp,%esp
c01095ad:	5d                   	pop    %ebp
c01095ae:	c3                   	ret    

c01095af <unlock_mm>:

static inline void
unlock_mm(struct mm_struct *mm) {
c01095af:	55                   	push   %ebp
c01095b0:	89 e5                	mov    %esp,%ebp
c01095b2:	83 ec 18             	sub    $0x18,%esp
    if (mm != NULL) {
c01095b5:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c01095b9:	74 0e                	je     c01095c9 <unlock_mm+0x1a>
        unlock(&(mm->mm_lock));
c01095bb:	8b 45 08             	mov    0x8(%ebp),%eax
c01095be:	83 c0 1c             	add    $0x1c,%eax
c01095c1:	89 04 24             	mov    %eax,(%esp)
c01095c4:	e8 40 fe ff ff       	call   c0109409 <unlock>
    }
}
c01095c9:	90                   	nop
c01095ca:	89 ec                	mov    %ebp,%esp
c01095cc:	5d                   	pop    %ebp
c01095cd:	c3                   	ret    

c01095ce <alloc_proc>:
void forkrets(struct trapframe *tf);
void switch_to(struct context *from, struct context *to);

// alloc_proc - alloc a proc_struct and init all fields of proc_struct
static struct proc_struct *
alloc_proc(void) {
c01095ce:	55                   	push   %ebp
c01095cf:	89 e5                	mov    %esp,%ebp
c01095d1:	83 ec 28             	sub    $0x28,%esp
    struct proc_struct *proc = kmalloc(sizeof(struct proc_struct));
c01095d4:	c7 04 24 7c 00 00 00 	movl   $0x7c,(%esp)
c01095db:	e8 10 b7 ff ff       	call   c0104cf0 <kmalloc>
c01095e0:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (proc != NULL) {
c01095e3:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01095e7:	0f 84 cd 00 00 00    	je     c01096ba <alloc_proc+0xec>
    /*
     * below fields(add in LAB5) in proc_struct need to be initialized	
     *       uint32_t wait_state;                        // waiting state
     *       struct proc_struct *cptr, *yptr, *optr;     // relations between processes
	 */
        proc->state = PROC_UNINIT; // 初始状态为未初始化
c01095ed:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01095f0:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
        proc->pid = -1;            // 初始进程ID为-1
c01095f6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01095f9:	c7 40 04 ff ff ff ff 	movl   $0xffffffff,0x4(%eax)
        proc->runs = 0;            // 初始运行次数为0
c0109600:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109603:	c7 40 08 00 00 00 00 	movl   $0x0,0x8(%eax)
        proc->kstack = 0;          // 初始内核栈指针为0
c010960a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010960d:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
        proc->need_resched = 0;    // 初始不需要重新调度
c0109614:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109617:	c7 40 10 00 00 00 00 	movl   $0x0,0x10(%eax)
        proc->parent = NULL;       // 初始父进程指针为NULL
c010961e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109621:	c7 40 14 00 00 00 00 	movl   $0x0,0x14(%eax)
        proc->mm = NULL;           // 初始内存管理结构指针为NULL
c0109628:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010962b:	c7 40 18 00 00 00 00 	movl   $0x0,0x18(%eax)
        memset(&proc->context, 0, sizeof(struct context));  // 初始化上下文切换信息
c0109632:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109635:	83 c0 1c             	add    $0x1c,%eax
c0109638:	c7 44 24 08 20 00 00 	movl   $0x20,0x8(%esp)
c010963f:	00 
c0109640:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0109647:	00 
c0109648:	89 04 24             	mov    %eax,(%esp)
c010964b:	e8 a1 27 00 00       	call   c010bdf1 <memset>
        proc->tf = NULL;           // 初始中断陷阱帧指针为NULL
c0109650:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109653:	c7 40 3c 00 00 00 00 	movl   $0x0,0x3c(%eax)
        proc->cr3 = boot_cr3;      // 初始CR3寄存器值为0
c010965a:	8b 15 a8 3f 1a c0    	mov    0xc01a3fa8,%edx
c0109660:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109663:	89 50 40             	mov    %edx,0x40(%eax)
        proc->flags = 0;           // 初始进程标志为0
c0109666:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109669:	c7 40 44 00 00 00 00 	movl   $0x0,0x44(%eax)
        memset(proc->name, 0, PROC_NAME_LEN);   // 初始进程名称为空字符串
c0109670:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109673:	83 c0 48             	add    $0x48,%eax
c0109676:	c7 44 24 08 0f 00 00 	movl   $0xf,0x8(%esp)
c010967d:	00 
c010967e:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0109685:	00 
c0109686:	89 04 24             	mov    %eax,(%esp)
c0109689:	e8 63 27 00 00       	call   c010bdf1 <memset>
        proc->wait_state = 0;
c010968e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109691:	c7 40 6c 00 00 00 00 	movl   $0x0,0x6c(%eax)
        proc->cptr = proc->optr = proc->yptr = NULL;
c0109698:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010969b:	c7 40 74 00 00 00 00 	movl   $0x0,0x74(%eax)
c01096a2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01096a5:	8b 50 74             	mov    0x74(%eax),%edx
c01096a8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01096ab:	89 50 78             	mov    %edx,0x78(%eax)
c01096ae:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01096b1:	8b 50 78             	mov    0x78(%eax),%edx
c01096b4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01096b7:	89 50 70             	mov    %edx,0x70(%eax)
    }
    return proc;
c01096ba:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01096bd:	89 ec                	mov    %ebp,%esp
c01096bf:	5d                   	pop    %ebp
c01096c0:	c3                   	ret    

c01096c1 <set_proc_name>:
 * @return 返回指向进程名称的指针，这是在内存中直接修改后的结果
 * 
 * 注意：此函数直接操作传入的进程结构体，对名称字段进行先清空后赋值的操作
 */
char *
set_proc_name(struct proc_struct *proc, const char *name) {
c01096c1:	55                   	push   %ebp
c01096c2:	89 e5                	mov    %esp,%ebp
c01096c4:	83 ec 18             	sub    $0x18,%esp
    
    // 清空进程名称字段中的现有内容，以准备存储新的名称
    memset(proc->name, 0, sizeof(proc->name));
c01096c7:	8b 45 08             	mov    0x8(%ebp),%eax
c01096ca:	83 c0 48             	add    $0x48,%eax
c01096cd:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
c01096d4:	00 
c01096d5:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01096dc:	00 
c01096dd:	89 04 24             	mov    %eax,(%esp)
c01096e0:	e8 0c 27 00 00       	call   c010bdf1 <memset>
    // 将新的名称复制到进程名称字段中
    return memcpy(proc->name, name, PROC_NAME_LEN);
c01096e5:	8b 45 08             	mov    0x8(%ebp),%eax
c01096e8:	8d 50 48             	lea    0x48(%eax),%edx
c01096eb:	c7 44 24 08 0f 00 00 	movl   $0xf,0x8(%esp)
c01096f2:	00 
c01096f3:	8b 45 0c             	mov    0xc(%ebp),%eax
c01096f6:	89 44 24 04          	mov    %eax,0x4(%esp)
c01096fa:	89 14 24             	mov    %edx,(%esp)
c01096fd:	e8 d4 27 00 00       	call   c010bed6 <memcpy>
}
c0109702:	89 ec                	mov    %ebp,%esp
c0109704:	5d                   	pop    %ebp
c0109705:	c3                   	ret    

c0109706 <get_proc_name>:

// get_proc_name - get the name of proc
char *
get_proc_name(struct proc_struct *proc) {
c0109706:	55                   	push   %ebp
c0109707:	89 e5                	mov    %esp,%ebp
c0109709:	83 ec 18             	sub    $0x18,%esp
    static char name[PROC_NAME_LEN + 1];
    memset(name, 0, sizeof(name));
c010970c:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
c0109713:	00 
c0109714:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010971b:	00 
c010971c:	c7 04 24 44 61 1a c0 	movl   $0xc01a6144,(%esp)
c0109723:	e8 c9 26 00 00       	call   c010bdf1 <memset>
    return memcpy(name, proc->name, PROC_NAME_LEN);
c0109728:	8b 45 08             	mov    0x8(%ebp),%eax
c010972b:	83 c0 48             	add    $0x48,%eax
c010972e:	c7 44 24 08 0f 00 00 	movl   $0xf,0x8(%esp)
c0109735:	00 
c0109736:	89 44 24 04          	mov    %eax,0x4(%esp)
c010973a:	c7 04 24 44 61 1a c0 	movl   $0xc01a6144,(%esp)
c0109741:	e8 90 27 00 00       	call   c010bed6 <memcpy>
}
c0109746:	89 ec                	mov    %ebp,%esp
c0109748:	5d                   	pop    %ebp
c0109749:	c3                   	ret    

c010974a <set_links>:

// set_links - set the relation links of process
static void
set_links(struct proc_struct *proc) {
c010974a:	55                   	push   %ebp
c010974b:	89 e5                	mov    %esp,%ebp
c010974d:	83 ec 20             	sub    $0x20,%esp
    list_add(&proc_list, &(proc->list_link));
c0109750:	8b 45 08             	mov    0x8(%ebp),%eax
c0109753:	83 c0 58             	add    $0x58,%eax
c0109756:	c7 45 fc 20 41 1a c0 	movl   $0xc01a4120,-0x4(%ebp)
c010975d:	89 45 f8             	mov    %eax,-0x8(%ebp)
c0109760:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0109763:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109766:	8b 45 f8             	mov    -0x8(%ebp),%eax
c0109769:	89 45 f0             	mov    %eax,-0x10(%ebp)
    __list_add(elm, listelm, listelm->next);
c010976c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010976f:	8b 40 04             	mov    0x4(%eax),%eax
c0109772:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0109775:	89 55 ec             	mov    %edx,-0x14(%ebp)
c0109778:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010977b:	89 55 e8             	mov    %edx,-0x18(%ebp)
c010977e:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    prev->next = next->prev = elm;
c0109781:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0109784:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0109787:	89 10                	mov    %edx,(%eax)
c0109789:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010978c:	8b 10                	mov    (%eax),%edx
c010978e:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109791:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0109794:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109797:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010979a:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c010979d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01097a0:	8b 55 e8             	mov    -0x18(%ebp),%edx
c01097a3:	89 10                	mov    %edx,(%eax)
}
c01097a5:	90                   	nop
}
c01097a6:	90                   	nop
}
c01097a7:	90                   	nop
    proc->yptr = NULL;
c01097a8:	8b 45 08             	mov    0x8(%ebp),%eax
c01097ab:	c7 40 74 00 00 00 00 	movl   $0x0,0x74(%eax)
    if ((proc->optr = proc->parent->cptr) != NULL) {
c01097b2:	8b 45 08             	mov    0x8(%ebp),%eax
c01097b5:	8b 40 14             	mov    0x14(%eax),%eax
c01097b8:	8b 50 70             	mov    0x70(%eax),%edx
c01097bb:	8b 45 08             	mov    0x8(%ebp),%eax
c01097be:	89 50 78             	mov    %edx,0x78(%eax)
c01097c1:	8b 45 08             	mov    0x8(%ebp),%eax
c01097c4:	8b 40 78             	mov    0x78(%eax),%eax
c01097c7:	85 c0                	test   %eax,%eax
c01097c9:	74 0c                	je     c01097d7 <set_links+0x8d>
        proc->optr->yptr = proc;
c01097cb:	8b 45 08             	mov    0x8(%ebp),%eax
c01097ce:	8b 40 78             	mov    0x78(%eax),%eax
c01097d1:	8b 55 08             	mov    0x8(%ebp),%edx
c01097d4:	89 50 74             	mov    %edx,0x74(%eax)
    }
    proc->parent->cptr = proc;
c01097d7:	8b 45 08             	mov    0x8(%ebp),%eax
c01097da:	8b 40 14             	mov    0x14(%eax),%eax
c01097dd:	8b 55 08             	mov    0x8(%ebp),%edx
c01097e0:	89 50 70             	mov    %edx,0x70(%eax)
    nr_process ++;
c01097e3:	a1 40 61 1a c0       	mov    0xc01a6140,%eax
c01097e8:	40                   	inc    %eax
c01097e9:	a3 40 61 1a c0       	mov    %eax,0xc01a6140
}
c01097ee:	90                   	nop
c01097ef:	89 ec                	mov    %ebp,%esp
c01097f1:	5d                   	pop    %ebp
c01097f2:	c3                   	ret    

c01097f3 <remove_links>:

// remove_links - clean the relation links of process
static void
remove_links(struct proc_struct *proc) {
c01097f3:	55                   	push   %ebp
c01097f4:	89 e5                	mov    %esp,%ebp
c01097f6:	83 ec 10             	sub    $0x10,%esp
    list_del(&(proc->list_link));
c01097f9:	8b 45 08             	mov    0x8(%ebp),%eax
c01097fc:	83 c0 58             	add    $0x58,%eax
c01097ff:	89 45 fc             	mov    %eax,-0x4(%ebp)
    __list_del(listelm->prev, listelm->next);
c0109802:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0109805:	8b 40 04             	mov    0x4(%eax),%eax
c0109808:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010980b:	8b 12                	mov    (%edx),%edx
c010980d:	89 55 f8             	mov    %edx,-0x8(%ebp)
c0109810:	89 45 f4             	mov    %eax,-0xc(%ebp)
    prev->next = next;
c0109813:	8b 45 f8             	mov    -0x8(%ebp),%eax
c0109816:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0109819:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c010981c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010981f:	8b 55 f8             	mov    -0x8(%ebp),%edx
c0109822:	89 10                	mov    %edx,(%eax)
}
c0109824:	90                   	nop
}
c0109825:	90                   	nop
    if (proc->optr != NULL) {
c0109826:	8b 45 08             	mov    0x8(%ebp),%eax
c0109829:	8b 40 78             	mov    0x78(%eax),%eax
c010982c:	85 c0                	test   %eax,%eax
c010982e:	74 0f                	je     c010983f <remove_links+0x4c>
        proc->optr->yptr = proc->yptr;
c0109830:	8b 45 08             	mov    0x8(%ebp),%eax
c0109833:	8b 40 78             	mov    0x78(%eax),%eax
c0109836:	8b 55 08             	mov    0x8(%ebp),%edx
c0109839:	8b 52 74             	mov    0x74(%edx),%edx
c010983c:	89 50 74             	mov    %edx,0x74(%eax)
    }
    if (proc->yptr != NULL) {
c010983f:	8b 45 08             	mov    0x8(%ebp),%eax
c0109842:	8b 40 74             	mov    0x74(%eax),%eax
c0109845:	85 c0                	test   %eax,%eax
c0109847:	74 11                	je     c010985a <remove_links+0x67>
        proc->yptr->optr = proc->optr;
c0109849:	8b 45 08             	mov    0x8(%ebp),%eax
c010984c:	8b 40 74             	mov    0x74(%eax),%eax
c010984f:	8b 55 08             	mov    0x8(%ebp),%edx
c0109852:	8b 52 78             	mov    0x78(%edx),%edx
c0109855:	89 50 78             	mov    %edx,0x78(%eax)
c0109858:	eb 0f                	jmp    c0109869 <remove_links+0x76>
    }
    else {
       proc->parent->cptr = proc->optr;
c010985a:	8b 45 08             	mov    0x8(%ebp),%eax
c010985d:	8b 40 14             	mov    0x14(%eax),%eax
c0109860:	8b 55 08             	mov    0x8(%ebp),%edx
c0109863:	8b 52 78             	mov    0x78(%edx),%edx
c0109866:	89 50 70             	mov    %edx,0x70(%eax)
    }
    nr_process --;
c0109869:	a1 40 61 1a c0       	mov    0xc01a6140,%eax
c010986e:	48                   	dec    %eax
c010986f:	a3 40 61 1a c0       	mov    %eax,0xc01a6140
}
c0109874:	90                   	nop
c0109875:	89 ec                	mov    %ebp,%esp
c0109877:	5d                   	pop    %ebp
c0109878:	c3                   	ret    

c0109879 <get_pid>:
 * 它使用静态变量来跟踪最后一个分配的PID和下一个安全PID，以提高效率并避免PID冲突。
 * 
 * @return 返回一个未被使用的进程ID。
 */
static int
get_pid(void) {
c0109879:	55                   	push   %ebp
c010987a:	89 e5                	mov    %esp,%ebp
c010987c:	83 ec 10             	sub    $0x10,%esp
    static_assert(MAX_PID > MAX_PROCESS);
    
    // 定义一个指向进程结构的指针，用于遍历进程列表。
    struct proc_struct *proc;
    // 初始化列表指针，从进程列表的头部开始。
    list_entry_t *list = &proc_list, *le;
c010987f:	c7 45 f8 20 41 1a c0 	movl   $0xc01a4120,-0x8(%ebp)
    // 定义静态变量，next_safe用于记录下一个安全的PID值，last_pid用于记录上一个分配的PID。
    static int next_safe = MAX_PID, last_pid = MAX_PID;

    // 尝试递增last_pid以查找下一个可用的PID，如果超过最大值则重置为1。
    if (++ last_pid >= MAX_PID) {
c0109886:	a1 80 fa 12 c0       	mov    0xc012fa80,%eax
c010988b:	40                   	inc    %eax
c010988c:	a3 80 fa 12 c0       	mov    %eax,0xc012fa80
c0109891:	a1 80 fa 12 c0       	mov    0xc012fa80,%eax
c0109896:	3d ff 1f 00 00       	cmp    $0x1fff,%eax
c010989b:	7e 0c                	jle    c01098a9 <get_pid+0x30>
        last_pid = 1;
c010989d:	c7 05 80 fa 12 c0 01 	movl   $0x1,0xc012fa80
c01098a4:	00 00 00 
        goto inside;
c01098a7:	eb 14                	jmp    c01098bd <get_pid+0x44>
    }

     // 如果当前的last_pid大于等于next_safe，表示需要重新计算下一个安全的PID。
    if (last_pid >= next_safe) {
c01098a9:	8b 15 80 fa 12 c0    	mov    0xc012fa80,%edx
c01098af:	a1 84 fa 12 c0       	mov    0xc012fa84,%eax
c01098b4:	39 c2                	cmp    %eax,%edx
c01098b6:	0f 8c ab 00 00 00    	jl     c0109967 <get_pid+0xee>
    inside:
c01098bc:	90                   	nop
        next_safe = MAX_PID;
c01098bd:	c7 05 84 fa 12 c0 00 	movl   $0x2000,0xc012fa84
c01098c4:	20 00 00 
    repeat:
        // 从进程列表的头部开始遍历。
        le = list;
c01098c7:	8b 45 f8             	mov    -0x8(%ebp),%eax
c01098ca:	89 45 fc             	mov    %eax,-0x4(%ebp)
        while ((le = list_next(le)) != list) {
c01098cd:	eb 7d                	jmp    c010994c <get_pid+0xd3>

            // 将列表项转换为进程结构。
            proc = le2proc(le, list_link);
c01098cf:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01098d2:	83 e8 58             	sub    $0x58,%eax
c01098d5:	89 45 f4             	mov    %eax,-0xc(%ebp)

        // 如果找到相同PID的进程，表示当前last_pid已被使用，需要继续寻找下一个可用的PID。
            if (proc->pid == last_pid) {
c01098d8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01098db:	8b 50 04             	mov    0x4(%eax),%edx
c01098de:	a1 80 fa 12 c0       	mov    0xc012fa80,%eax
c01098e3:	39 c2                	cmp    %eax,%edx
c01098e5:	75 3c                	jne    c0109923 <get_pid+0xaa>
                if (++ last_pid >= next_safe) {
c01098e7:	a1 80 fa 12 c0       	mov    0xc012fa80,%eax
c01098ec:	40                   	inc    %eax
c01098ed:	a3 80 fa 12 c0       	mov    %eax,0xc012fa80
c01098f2:	8b 15 80 fa 12 c0    	mov    0xc012fa80,%edx
c01098f8:	a1 84 fa 12 c0       	mov    0xc012fa84,%eax
c01098fd:	39 c2                	cmp    %eax,%edx
c01098ff:	7c 4b                	jl     c010994c <get_pid+0xd3>
                    if (last_pid >= MAX_PID) {
c0109901:	a1 80 fa 12 c0       	mov    0xc012fa80,%eax
c0109906:	3d ff 1f 00 00       	cmp    $0x1fff,%eax
c010990b:	7e 0a                	jle    c0109917 <get_pid+0x9e>
                        last_pid = 1;
c010990d:	c7 05 80 fa 12 c0 01 	movl   $0x1,0xc012fa80
c0109914:	00 00 00 
                    }
                    next_safe = MAX_PID;
c0109917:	c7 05 84 fa 12 c0 00 	movl   $0x2000,0xc012fa84
c010991e:	20 00 00 
                    goto repeat;
c0109921:	eb a4                	jmp    c01098c7 <get_pid+0x4e>
                }
            }

            // 如果找到一个更大的PID，更新next_safe为当前进程的PID，以确保找到的PID是安全的。
            else if (proc->pid > last_pid && next_safe > proc->pid) {
c0109923:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109926:	8b 50 04             	mov    0x4(%eax),%edx
c0109929:	a1 80 fa 12 c0       	mov    0xc012fa80,%eax
c010992e:	39 c2                	cmp    %eax,%edx
c0109930:	7e 1a                	jle    c010994c <get_pid+0xd3>
c0109932:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109935:	8b 50 04             	mov    0x4(%eax),%edx
c0109938:	a1 84 fa 12 c0       	mov    0xc012fa84,%eax
c010993d:	39 c2                	cmp    %eax,%edx
c010993f:	7d 0b                	jge    c010994c <get_pid+0xd3>
                next_safe = proc->pid;
c0109941:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109944:	8b 40 04             	mov    0x4(%eax),%eax
c0109947:	a3 84 fa 12 c0       	mov    %eax,0xc012fa84
c010994c:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010994f:	89 45 f0             	mov    %eax,-0x10(%ebp)
    return listelm->next;
c0109952:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109955:	8b 40 04             	mov    0x4(%eax),%eax
        while ((le = list_next(le)) != list) {
c0109958:	89 45 fc             	mov    %eax,-0x4(%ebp)
c010995b:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010995e:	3b 45 f8             	cmp    -0x8(%ebp),%eax
c0109961:	0f 85 68 ff ff ff    	jne    c01098cf <get_pid+0x56>
            }
        }
    }
    // 返回找到的可用PID。
    return last_pid;
c0109967:	a1 80 fa 12 c0       	mov    0xc012fa80,%eax
}
c010996c:	89 ec                	mov    %ebp,%esp
c010996e:	5d                   	pop    %ebp
c010996f:	c3                   	ret    

c0109970 <proc_run>:

// proc_run - make process "proc" running on cpu
// NOTE: before call switch_to, should load  base addr of "proc"'s new PDT
//切换当前运行的进程
void
proc_run(struct proc_struct *proc) {
c0109970:	55                   	push   %ebp
c0109971:	89 e5                	mov    %esp,%ebp
c0109973:	83 ec 28             	sub    $0x28,%esp
    if (proc != current) {
c0109976:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010997b:	39 45 08             	cmp    %eax,0x8(%ebp)
c010997e:	74 64                	je     c01099e4 <proc_run+0x74>
        bool intr_flag;
        struct proc_struct *prev = current, *next = proc;
c0109980:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c0109985:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109988:	8b 45 08             	mov    0x8(%ebp),%eax
c010998b:	89 45 f0             	mov    %eax,-0x10(%ebp)
        local_intr_save(intr_flag);
c010998e:	e8 ed f9 ff ff       	call   c0109380 <__intr_save>
c0109993:	89 45 ec             	mov    %eax,-0x14(%ebp)
        {
            current = proc;
c0109996:	8b 45 08             	mov    0x8(%ebp),%eax
c0109999:	a3 30 41 1a c0       	mov    %eax,0xc01a4130
            load_esp0(next->kstack + KSTACKSIZE);
c010999e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01099a1:	8b 40 0c             	mov    0xc(%eax),%eax
c01099a4:	05 00 20 00 00       	add    $0x2000,%eax
c01099a9:	89 04 24             	mov    %eax,(%esp)
c01099ac:	e8 7e b6 ff ff       	call   c010502f <load_esp0>
            lcr3(next->cr3);
c01099b1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01099b4:	8b 40 40             	mov    0x40(%eax),%eax
c01099b7:	89 45 e8             	mov    %eax,-0x18(%ebp)
    asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory");
c01099ba:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01099bd:	0f 22 d8             	mov    %eax,%cr3
}
c01099c0:	90                   	nop
            switch_to(&(prev->context), &(next->context));
c01099c1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01099c4:	8d 50 1c             	lea    0x1c(%eax),%edx
c01099c7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01099ca:	83 c0 1c             	add    $0x1c,%eax
c01099cd:	89 54 24 04          	mov    %edx,0x4(%esp)
c01099d1:	89 04 24             	mov    %eax,(%esp)
c01099d4:	e8 a3 15 00 00       	call   c010af7c <switch_to>
        }
        local_intr_restore(intr_flag);
c01099d9:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01099dc:	89 04 24             	mov    %eax,(%esp)
c01099df:	e8 c8 f9 ff ff       	call   c01093ac <__intr_restore>
    }
}
c01099e4:	90                   	nop
c01099e5:	89 ec                	mov    %ebp,%esp
c01099e7:	5d                   	pop    %ebp
c01099e8:	c3                   	ret    

c01099e9 <forkret>:
// forkret -- the first kernel entry point of a new thread/process
// NOTE: the addr of forkret is setted in copy_thread function
//       after switch_to, the current proc will execute here.
// 函数在调用时会传递当前进程的线程上下文（通过 current->tf 获取）给 forkrets 函数。
static void
forkret(void) {
c01099e9:	55                   	push   %ebp
c01099ea:	89 e5                	mov    %esp,%ebp
c01099ec:	83 ec 18             	sub    $0x18,%esp
    forkrets(current->tf);
c01099ef:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c01099f4:	8b 40 3c             	mov    0x3c(%eax),%eax
c01099f7:	89 04 24             	mov    %eax,(%esp)
c01099fa:	e8 67 90 ff ff       	call   c0102a66 <forkrets>
}
c01099ff:	90                   	nop
c0109a00:	89 ec                	mov    %ebp,%esp
c0109a02:	5d                   	pop    %ebp
c0109a03:	c3                   	ret    

c0109a04 <hash_proc>:
 * 这有助于在需要时快速查找进程
 * 
 * @param proc 指向进程结构体的指针，表示要添加到哈希表的进程
 */
static void
hash_proc(struct proc_struct *proc) {
c0109a04:	55                   	push   %ebp
c0109a05:	89 e5                	mov    %esp,%ebp
c0109a07:	83 ec 38             	sub    $0x38,%esp
c0109a0a:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    // 根据进程的PID计算哈希值，并将进程添加到相应哈希链表的末尾
    list_add(hash_list + pid_hashfn(proc->pid), &(proc->hash_link));
c0109a0d:	8b 45 08             	mov    0x8(%ebp),%eax
c0109a10:	8d 58 60             	lea    0x60(%eax),%ebx
c0109a13:	8b 45 08             	mov    0x8(%ebp),%eax
c0109a16:	8b 40 04             	mov    0x4(%eax),%eax
c0109a19:	c7 44 24 04 0a 00 00 	movl   $0xa,0x4(%esp)
c0109a20:	00 
c0109a21:	89 04 24             	mov    %eax,(%esp)
c0109a24:	e8 2b 19 00 00       	call   c010b354 <hash32>
c0109a29:	c1 e0 03             	shl    $0x3,%eax
c0109a2c:	05 40 41 1a c0       	add    $0xc01a4140,%eax
c0109a31:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109a34:	89 5d f0             	mov    %ebx,-0x10(%ebp)
c0109a37:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109a3a:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0109a3d:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109a40:	89 45 e8             	mov    %eax,-0x18(%ebp)
    __list_add(elm, listelm, listelm->next);
c0109a43:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109a46:	8b 40 04             	mov    0x4(%eax),%eax
c0109a49:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0109a4c:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c0109a4f:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0109a52:	89 55 e0             	mov    %edx,-0x20(%ebp)
c0109a55:	89 45 dc             	mov    %eax,-0x24(%ebp)
    prev->next = next->prev = elm;
c0109a58:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0109a5b:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0109a5e:	89 10                	mov    %edx,(%eax)
c0109a60:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0109a63:	8b 10                	mov    (%eax),%edx
c0109a65:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0109a68:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0109a6b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0109a6e:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0109a71:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0109a74:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0109a77:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0109a7a:	89 10                	mov    %edx,(%eax)
}
c0109a7c:	90                   	nop
}
c0109a7d:	90                   	nop
}
c0109a7e:	90                   	nop
}
c0109a7f:	90                   	nop
c0109a80:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c0109a83:	89 ec                	mov    %ebp,%esp
c0109a85:	5d                   	pop    %ebp
c0109a86:	c3                   	ret    

c0109a87 <unhash_proc>:

// unhash_proc - delete proc from proc hash_list
static void
unhash_proc(struct proc_struct *proc) {
c0109a87:	55                   	push   %ebp
c0109a88:	89 e5                	mov    %esp,%ebp
c0109a8a:	83 ec 10             	sub    $0x10,%esp
    list_del(&(proc->hash_link));
c0109a8d:	8b 45 08             	mov    0x8(%ebp),%eax
c0109a90:	83 c0 60             	add    $0x60,%eax
c0109a93:	89 45 fc             	mov    %eax,-0x4(%ebp)
    __list_del(listelm->prev, listelm->next);
c0109a96:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0109a99:	8b 40 04             	mov    0x4(%eax),%eax
c0109a9c:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0109a9f:	8b 12                	mov    (%edx),%edx
c0109aa1:	89 55 f8             	mov    %edx,-0x8(%ebp)
c0109aa4:	89 45 f4             	mov    %eax,-0xc(%ebp)
    prev->next = next;
c0109aa7:	8b 45 f8             	mov    -0x8(%ebp),%eax
c0109aaa:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0109aad:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0109ab0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109ab3:	8b 55 f8             	mov    -0x8(%ebp),%edx
c0109ab6:	89 10                	mov    %edx,(%eax)
}
c0109ab8:	90                   	nop
}
c0109ab9:	90                   	nop
}
c0109aba:	90                   	nop
c0109abb:	89 ec                	mov    %ebp,%esp
c0109abd:	5d                   	pop    %ebp
c0109abe:	c3                   	ret    

c0109abf <find_proc>:

// find_proc - find proc frome proc hash_list according to pid
struct proc_struct *
find_proc(int pid) {
c0109abf:	55                   	push   %ebp
c0109ac0:	89 e5                	mov    %esp,%ebp
c0109ac2:	83 ec 28             	sub    $0x28,%esp
    if (0 < pid && pid < MAX_PID) {
c0109ac5:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0109ac9:	7e 5f                	jle    c0109b2a <find_proc+0x6b>
c0109acb:	81 7d 08 ff 1f 00 00 	cmpl   $0x1fff,0x8(%ebp)
c0109ad2:	7f 56                	jg     c0109b2a <find_proc+0x6b>
        list_entry_t *list = hash_list + pid_hashfn(pid), *le = list;
c0109ad4:	8b 45 08             	mov    0x8(%ebp),%eax
c0109ad7:	c7 44 24 04 0a 00 00 	movl   $0xa,0x4(%esp)
c0109ade:	00 
c0109adf:	89 04 24             	mov    %eax,(%esp)
c0109ae2:	e8 6d 18 00 00       	call   c010b354 <hash32>
c0109ae7:	c1 e0 03             	shl    $0x3,%eax
c0109aea:	05 40 41 1a c0       	add    $0xc01a4140,%eax
c0109aef:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109af2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109af5:	89 45 f4             	mov    %eax,-0xc(%ebp)
        while ((le = list_next(le)) != list) {
c0109af8:	eb 19                	jmp    c0109b13 <find_proc+0x54>
            struct proc_struct *proc = le2proc(le, hash_link);
c0109afa:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109afd:	83 e8 60             	sub    $0x60,%eax
c0109b00:	89 45 ec             	mov    %eax,-0x14(%ebp)
            if (proc->pid == pid) {
c0109b03:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109b06:	8b 40 04             	mov    0x4(%eax),%eax
c0109b09:	39 45 08             	cmp    %eax,0x8(%ebp)
c0109b0c:	75 05                	jne    c0109b13 <find_proc+0x54>
                return proc;
c0109b0e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109b11:	eb 1c                	jmp    c0109b2f <find_proc+0x70>
c0109b13:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109b16:	89 45 e8             	mov    %eax,-0x18(%ebp)
    return listelm->next;
c0109b19:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109b1c:	8b 40 04             	mov    0x4(%eax),%eax
        while ((le = list_next(le)) != list) {
c0109b1f:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109b22:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109b25:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c0109b28:	75 d0                	jne    c0109afa <find_proc+0x3b>
            }
        }
    }
    return NULL;
c0109b2a:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0109b2f:	89 ec                	mov    %ebp,%esp
c0109b31:	5d                   	pop    %ebp
c0109b32:	c3                   	ret    

c0109b33 <kernel_thread>:
 * 
 * 该函数通过设置trapframe来创建一个内核线程，并安排其执行指定的函数fn
 * 使用do_fork函数来进行实际的线程创建操作，创建的线程将共享父线程的虚拟内存
 */
int
kernel_thread(int (*fn)(void *), void *arg, uint32_t clone_flags) {
c0109b33:	55                   	push   %ebp
c0109b34:	89 e5                	mov    %esp,%ebp
c0109b36:	83 ec 68             	sub    $0x68,%esp
    // 初始化trapframe结构体，用于描述线程的初始状态
    struct trapframe tf;
    memset(&tf, 0, sizeof(struct trapframe));
c0109b39:	c7 44 24 08 4c 00 00 	movl   $0x4c,0x8(%esp)
c0109b40:	00 
c0109b41:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0109b48:	00 
c0109b49:	8d 45 ac             	lea    -0x54(%ebp),%eax
c0109b4c:	89 04 24             	mov    %eax,(%esp)
c0109b4f:	e8 9d 22 00 00       	call   c010bdf1 <memset>

    // 设置代码段和数据段寄存器的值，使线程运行在内核态
    tf.tf_cs = KERNEL_CS;
c0109b54:	66 c7 45 e8 08 00    	movw   $0x8,-0x18(%ebp)
    tf.tf_ds = tf.tf_es = tf.tf_ss = KERNEL_DS;
c0109b5a:	66 c7 45 f4 10 00    	movw   $0x10,-0xc(%ebp)
c0109b60:	0f b7 45 f4          	movzwl -0xc(%ebp),%eax
c0109b64:	66 89 45 d4          	mov    %ax,-0x2c(%ebp)
c0109b68:	0f b7 45 d4          	movzwl -0x2c(%ebp),%eax
c0109b6c:	66 89 45 d8          	mov    %ax,-0x28(%ebp)

    // 将要执行的函数fn的地址和参数arg的地址分别放入ebx和edx寄存器
    tf.tf_regs.reg_ebx = (uint32_t)fn;
c0109b70:	8b 45 08             	mov    0x8(%ebp),%eax
c0109b73:	89 45 bc             	mov    %eax,-0x44(%ebp)
    tf.tf_regs.reg_edx = (uint32_t)arg;
c0109b76:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109b79:	89 45 c0             	mov    %eax,-0x40(%ebp)

    // 设置指令指针寄存器eip，使其指向内核线程入口函数kernel_thread_entry
    tf.tf_eip = (uint32_t)kernel_thread_entry;
c0109b7c:	b8 33 93 10 c0       	mov    $0xc0109333,%eax
c0109b81:	89 45 e4             	mov    %eax,-0x1c(%ebp)

    // 调用do_fork函数创建新线程，新线程将共享父线程的虚拟内存
    // 并将新线程的初始状态设置为之前准备的trapframe
    return do_fork(clone_flags | CLONE_VM, 0, &tf);
c0109b84:	8b 45 10             	mov    0x10(%ebp),%eax
c0109b87:	0d 00 01 00 00       	or     $0x100,%eax
c0109b8c:	89 c2                	mov    %eax,%edx
c0109b8e:	8d 45 ac             	lea    -0x54(%ebp),%eax
c0109b91:	89 44 24 08          	mov    %eax,0x8(%esp)
c0109b95:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0109b9c:	00 
c0109b9d:	89 14 24             	mov    %edx,(%esp)
c0109ba0:	e8 44 03 00 00       	call   c0109ee9 <do_fork>
}
c0109ba5:	89 ec                	mov    %ebp,%esp
c0109ba7:	5d                   	pop    %ebp
c0109ba8:	c3                   	ret    

c0109ba9 <setup_kstack>:
 * 
 * 此函数通过分配一页内存用作进程的内核栈，并将该内存页的虚拟地址设置为进程的内核栈地址
 * 如果内存分配成功，则返回0；如果内存分配失败，则返回-E_NO_MEM
 */
static int
setup_kstack(struct proc_struct *proc) {
c0109ba9:	55                   	push   %ebp
c0109baa:	89 e5                	mov    %esp,%ebp
c0109bac:	83 ec 28             	sub    $0x28,%esp
    // 分配KSTACKPAGE页内存用作内核栈
    struct Page *page = alloc_pages(KSTACKPAGE);
c0109baf:	c7 04 24 02 00 00 00 	movl   $0x2,(%esp)
c0109bb6:	e8 c6 b5 ff ff       	call   c0105181 <alloc_pages>
c0109bbb:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (page != NULL) {
c0109bbe:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0109bc2:	74 1a                	je     c0109bde <setup_kstack+0x35>
        // 如果内存分配成功，将内存页的虚拟地址设置为进程的内核栈地址
        proc->kstack = (uintptr_t)page2kva(page);
c0109bc4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109bc7:	89 04 24             	mov    %eax,(%esp)
c0109bca:	e8 eb f8 ff ff       	call   c01094ba <page2kva>
c0109bcf:	89 c2                	mov    %eax,%edx
c0109bd1:	8b 45 08             	mov    0x8(%ebp),%eax
c0109bd4:	89 50 0c             	mov    %edx,0xc(%eax)
        return 0;
c0109bd7:	b8 00 00 00 00       	mov    $0x0,%eax
c0109bdc:	eb 05                	jmp    c0109be3 <setup_kstack+0x3a>
    }
    // 如果内存分配失败，返回错误码
    return -E_NO_MEM;
c0109bde:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
}
c0109be3:	89 ec                	mov    %ebp,%esp
c0109be5:	5d                   	pop    %ebp
c0109be6:	c3                   	ret    

c0109be7 <put_kstack>:

// put_kstack - free the memory space of process kernel stack
static void
put_kstack(struct proc_struct *proc) {
c0109be7:	55                   	push   %ebp
c0109be8:	89 e5                	mov    %esp,%ebp
c0109bea:	83 ec 18             	sub    $0x18,%esp
    free_pages(kva2page((void *)(proc->kstack)), KSTACKPAGE);
c0109bed:	8b 45 08             	mov    0x8(%ebp),%eax
c0109bf0:	8b 40 0c             	mov    0xc(%eax),%eax
c0109bf3:	89 04 24             	mov    %eax,(%esp)
c0109bf6:	e8 15 f9 ff ff       	call   c0109510 <kva2page>
c0109bfb:	c7 44 24 04 02 00 00 	movl   $0x2,0x4(%esp)
c0109c02:	00 
c0109c03:	89 04 24             	mov    %eax,(%esp)
c0109c06:	e8 e3 b5 ff ff       	call   c01051ee <free_pages>
}
c0109c0b:	90                   	nop
c0109c0c:	89 ec                	mov    %ebp,%esp
c0109c0e:	5d                   	pop    %ebp
c0109c0f:	c3                   	ret    

c0109c10 <setup_pgdir>:

// setup_pgdir - alloc one page as PDT
static int
setup_pgdir(struct mm_struct *mm) {
c0109c10:	55                   	push   %ebp
c0109c11:	89 e5                	mov    %esp,%ebp
c0109c13:	83 ec 28             	sub    $0x28,%esp
    struct Page *page;
    if ((page = alloc_page()) == NULL) {
c0109c16:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0109c1d:	e8 5f b5 ff ff       	call   c0105181 <alloc_pages>
c0109c22:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109c25:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0109c29:	75 0a                	jne    c0109c35 <setup_pgdir+0x25>
        return -E_NO_MEM;
c0109c2b:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
c0109c30:	e9 80 00 00 00       	jmp    c0109cb5 <setup_pgdir+0xa5>
    }
    pde_t *pgdir = page2kva(page);
c0109c35:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109c38:	89 04 24             	mov    %eax,(%esp)
c0109c3b:	e8 7a f8 ff ff       	call   c01094ba <page2kva>
c0109c40:	89 45 f0             	mov    %eax,-0x10(%ebp)
    memcpy(pgdir, boot_pgdir, PGSIZE);
c0109c43:	a1 00 fa 12 c0       	mov    0xc012fa00,%eax
c0109c48:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0109c4f:	00 
c0109c50:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109c54:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109c57:	89 04 24             	mov    %eax,(%esp)
c0109c5a:	e8 77 22 00 00       	call   c010bed6 <memcpy>
    pgdir[PDX(VPT)] = PADDR(pgdir) | PTE_P | PTE_W;
c0109c5f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109c62:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0109c65:	81 7d ec ff ff ff bf 	cmpl   $0xbfffffff,-0x14(%ebp)
c0109c6c:	77 23                	ja     c0109c91 <setup_pgdir+0x81>
c0109c6e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109c71:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0109c75:	c7 44 24 08 78 e0 10 	movl   $0xc010e078,0x8(%esp)
c0109c7c:	c0 
c0109c7d:	c7 44 24 04 84 01 00 	movl   $0x184,0x4(%esp)
c0109c84:	00 
c0109c85:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c0109c8c:	e8 aa 70 ff ff       	call   c0100d3b <__panic>
c0109c91:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109c94:	8d 90 00 00 00 40    	lea    0x40000000(%eax),%edx
c0109c9a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109c9d:	05 ac 0f 00 00       	add    $0xfac,%eax
c0109ca2:	83 ca 03             	or     $0x3,%edx
c0109ca5:	89 10                	mov    %edx,(%eax)
    mm->pgdir = pgdir;
c0109ca7:	8b 45 08             	mov    0x8(%ebp),%eax
c0109caa:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0109cad:	89 50 0c             	mov    %edx,0xc(%eax)
    return 0;
c0109cb0:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0109cb5:	89 ec                	mov    %ebp,%esp
c0109cb7:	5d                   	pop    %ebp
c0109cb8:	c3                   	ret    

c0109cb9 <put_pgdir>:

// put_pgdir - free the memory space of PDT
static void
put_pgdir(struct mm_struct *mm) {
c0109cb9:	55                   	push   %ebp
c0109cba:	89 e5                	mov    %esp,%ebp
c0109cbc:	83 ec 18             	sub    $0x18,%esp
    free_page(kva2page(mm->pgdir));
c0109cbf:	8b 45 08             	mov    0x8(%ebp),%eax
c0109cc2:	8b 40 0c             	mov    0xc(%eax),%eax
c0109cc5:	89 04 24             	mov    %eax,(%esp)
c0109cc8:	e8 43 f8 ff ff       	call   c0109510 <kva2page>
c0109ccd:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0109cd4:	00 
c0109cd5:	89 04 24             	mov    %eax,(%esp)
c0109cd8:	e8 11 b5 ff ff       	call   c01051ee <free_pages>
}
c0109cdd:	90                   	nop
c0109cde:	89 ec                	mov    %ebp,%esp
c0109ce0:	5d                   	pop    %ebp
c0109ce1:	c3                   	ret    

c0109ce2 <copy_mm>:

// copy_mm - process "proc" duplicate OR share process "current"'s mm according clone_flags
//         - if clone_flags & CLONE_VM, then "share" ; else "duplicate"
static int
copy_mm(uint32_t clone_flags, struct proc_struct *proc) {
c0109ce2:	55                   	push   %ebp
c0109ce3:	89 e5                	mov    %esp,%ebp
c0109ce5:	83 ec 28             	sub    $0x28,%esp
    struct mm_struct *mm, *oldmm = current->mm;
c0109ce8:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c0109ced:	8b 40 18             	mov    0x18(%eax),%eax
c0109cf0:	89 45 ec             	mov    %eax,-0x14(%ebp)

    /* current is a kernel thread */
    if (oldmm == NULL) {
c0109cf3:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0109cf7:	75 0a                	jne    c0109d03 <copy_mm+0x21>
        return 0;
c0109cf9:	b8 00 00 00 00       	mov    $0x0,%eax
c0109cfe:	e9 fc 00 00 00       	jmp    c0109dff <copy_mm+0x11d>
    }
    if (clone_flags & CLONE_VM) {
c0109d03:	8b 45 08             	mov    0x8(%ebp),%eax
c0109d06:	25 00 01 00 00       	and    $0x100,%eax
c0109d0b:	85 c0                	test   %eax,%eax
c0109d0d:	74 08                	je     c0109d17 <copy_mm+0x35>
        mm = oldmm;
c0109d0f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109d12:	89 45 f4             	mov    %eax,-0xc(%ebp)
        goto good_mm;
c0109d15:	eb 5e                	jmp    c0109d75 <copy_mm+0x93>
    }

    int ret = -E_NO_MEM;
c0109d17:	c7 45 f0 fc ff ff ff 	movl   $0xfffffffc,-0x10(%ebp)
    if ((mm = mm_create()) == NULL) {
c0109d1e:	e8 92 e2 ff ff       	call   c0107fb5 <mm_create>
c0109d23:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109d26:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0109d2a:	0f 84 cb 00 00 00    	je     c0109dfb <copy_mm+0x119>
        goto bad_mm;
    }
    if (setup_pgdir(mm) != 0) {
c0109d30:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109d33:	89 04 24             	mov    %eax,(%esp)
c0109d36:	e8 d5 fe ff ff       	call   c0109c10 <setup_pgdir>
c0109d3b:	85 c0                	test   %eax,%eax
c0109d3d:	0f 85 aa 00 00 00    	jne    c0109ded <copy_mm+0x10b>
        goto bad_pgdir_cleanup_mm;
    }

    lock_mm(oldmm);
c0109d43:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109d46:	89 04 24             	mov    %eax,(%esp)
c0109d49:	e8 42 f8 ff ff       	call   c0109590 <lock_mm>
    {
        ret = dup_mmap(mm, oldmm);
c0109d4e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109d51:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109d55:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109d58:	89 04 24             	mov    %eax,(%esp)
c0109d5b:	e8 4c e7 ff ff       	call   c01084ac <dup_mmap>
c0109d60:	89 45 f0             	mov    %eax,-0x10(%ebp)
    }
    unlock_mm(oldmm);
c0109d63:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109d66:	89 04 24             	mov    %eax,(%esp)
c0109d69:	e8 41 f8 ff ff       	call   c01095af <unlock_mm>

    if (ret != 0) {
c0109d6e:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0109d72:	75 60                	jne    c0109dd4 <copy_mm+0xf2>
        goto bad_dup_cleanup_mmap;
    }

good_mm:
c0109d74:	90                   	nop
    mm_count_inc(mm);
c0109d75:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109d78:	89 04 24             	mov    %eax,(%esp)
c0109d7b:	e8 dc f7 ff ff       	call   c010955c <mm_count_inc>
    proc->mm = mm;
c0109d80:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109d83:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0109d86:	89 50 18             	mov    %edx,0x18(%eax)
    proc->cr3 = PADDR(mm->pgdir);
c0109d89:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109d8c:	8b 40 0c             	mov    0xc(%eax),%eax
c0109d8f:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0109d92:	81 7d e8 ff ff ff bf 	cmpl   $0xbfffffff,-0x18(%ebp)
c0109d99:	77 23                	ja     c0109dbe <copy_mm+0xdc>
c0109d9b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109d9e:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0109da2:	c7 44 24 08 78 e0 10 	movl   $0xc010e078,0x8(%esp)
c0109da9:	c0 
c0109daa:	c7 44 24 04 b3 01 00 	movl   $0x1b3,0x4(%esp)
c0109db1:	00 
c0109db2:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c0109db9:	e8 7d 6f ff ff       	call   c0100d3b <__panic>
c0109dbe:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109dc1:	8d 90 00 00 00 40    	lea    0x40000000(%eax),%edx
c0109dc7:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109dca:	89 50 40             	mov    %edx,0x40(%eax)
    return 0;
c0109dcd:	b8 00 00 00 00       	mov    $0x0,%eax
c0109dd2:	eb 2b                	jmp    c0109dff <copy_mm+0x11d>
        goto bad_dup_cleanup_mmap;
c0109dd4:	90                   	nop
bad_dup_cleanup_mmap:
    exit_mmap(mm);
c0109dd5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109dd8:	89 04 24             	mov    %eax,(%esp)
c0109ddb:	e8 cd e7 ff ff       	call   c01085ad <exit_mmap>
    put_pgdir(mm);
c0109de0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109de3:	89 04 24             	mov    %eax,(%esp)
c0109de6:	e8 ce fe ff ff       	call   c0109cb9 <put_pgdir>
c0109deb:	eb 01                	jmp    c0109dee <copy_mm+0x10c>
        goto bad_pgdir_cleanup_mm;
c0109ded:	90                   	nop
bad_pgdir_cleanup_mm:
    mm_destroy(mm);
c0109dee:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109df1:	89 04 24             	mov    %eax,(%esp)
c0109df4:	e8 25 e5 ff ff       	call   c010831e <mm_destroy>
c0109df9:	eb 01                	jmp    c0109dfc <copy_mm+0x11a>
        goto bad_mm;
c0109dfb:	90                   	nop
bad_mm:
    return ret;
c0109dfc:	8b 45 f0             	mov    -0x10(%ebp),%eax
}
c0109dff:	89 ec                	mov    %ebp,%esp
c0109e01:	5d                   	pop    %ebp
c0109e02:	c3                   	ret    

c0109e03 <copy_thread>:
 * @param proc 指向新进程的进程结构体，用于存储初始化后的陷阱帧和上下文信息。
 * @param esp 新进程的栈指针，表示新进程栈的初始位置。
 * @param tf 指向当前线程的陷阱帧结构体，用于将当前线程的执行状态复制到新进程中。
 */
static void
copy_thread(struct proc_struct *proc, uintptr_t esp, struct trapframe *tf) {
c0109e03:	55                   	push   %ebp
c0109e04:	89 e5                	mov    %esp,%ebp
c0109e06:	57                   	push   %edi
c0109e07:	56                   	push   %esi
c0109e08:	53                   	push   %ebx
    // 初始化新进程的陷阱帧，位于其内核栈的顶部
    proc->tf = (struct trapframe *)(proc->kstack + KSTACKSIZE) - 1;
c0109e09:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e0c:	8b 40 0c             	mov    0xc(%eax),%eax
c0109e0f:	05 b4 1f 00 00       	add    $0x1fb4,%eax
c0109e14:	89 c2                	mov    %eax,%edx
c0109e16:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e19:	89 50 3c             	mov    %edx,0x3c(%eax)

    // 将当前线程的陷阱帧内容复制到新进程的陷阱帧
    *(proc->tf) = *tf;
c0109e1c:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e1f:	8b 40 3c             	mov    0x3c(%eax),%eax
c0109e22:	8b 55 10             	mov    0x10(%ebp),%edx
c0109e25:	b9 4c 00 00 00       	mov    $0x4c,%ecx
c0109e2a:	89 c3                	mov    %eax,%ebx
c0109e2c:	83 e3 01             	and    $0x1,%ebx
c0109e2f:	85 db                	test   %ebx,%ebx
c0109e31:	74 0c                	je     c0109e3f <copy_thread+0x3c>
c0109e33:	0f b6 1a             	movzbl (%edx),%ebx
c0109e36:	88 18                	mov    %bl,(%eax)
c0109e38:	8d 40 01             	lea    0x1(%eax),%eax
c0109e3b:	8d 52 01             	lea    0x1(%edx),%edx
c0109e3e:	49                   	dec    %ecx
c0109e3f:	89 c3                	mov    %eax,%ebx
c0109e41:	83 e3 02             	and    $0x2,%ebx
c0109e44:	85 db                	test   %ebx,%ebx
c0109e46:	74 0f                	je     c0109e57 <copy_thread+0x54>
c0109e48:	0f b7 1a             	movzwl (%edx),%ebx
c0109e4b:	66 89 18             	mov    %bx,(%eax)
c0109e4e:	8d 40 02             	lea    0x2(%eax),%eax
c0109e51:	8d 52 02             	lea    0x2(%edx),%edx
c0109e54:	83 e9 02             	sub    $0x2,%ecx
c0109e57:	89 cf                	mov    %ecx,%edi
c0109e59:	83 e7 fc             	and    $0xfffffffc,%edi
c0109e5c:	bb 00 00 00 00       	mov    $0x0,%ebx
c0109e61:	8b 34 1a             	mov    (%edx,%ebx,1),%esi
c0109e64:	89 34 18             	mov    %esi,(%eax,%ebx,1)
c0109e67:	83 c3 04             	add    $0x4,%ebx
c0109e6a:	39 fb                	cmp    %edi,%ebx
c0109e6c:	72 f3                	jb     c0109e61 <copy_thread+0x5e>
c0109e6e:	01 d8                	add    %ebx,%eax
c0109e70:	01 da                	add    %ebx,%edx
c0109e72:	bb 00 00 00 00       	mov    $0x0,%ebx
c0109e77:	89 ce                	mov    %ecx,%esi
c0109e79:	83 e6 02             	and    $0x2,%esi
c0109e7c:	85 f6                	test   %esi,%esi
c0109e7e:	74 0b                	je     c0109e8b <copy_thread+0x88>
c0109e80:	0f b7 34 1a          	movzwl (%edx,%ebx,1),%esi
c0109e84:	66 89 34 18          	mov    %si,(%eax,%ebx,1)
c0109e88:	83 c3 02             	add    $0x2,%ebx
c0109e8b:	83 e1 01             	and    $0x1,%ecx
c0109e8e:	85 c9                	test   %ecx,%ecx
c0109e90:	74 07                	je     c0109e99 <copy_thread+0x96>
c0109e92:	0f b6 14 1a          	movzbl (%edx,%ebx,1),%edx
c0109e96:	88 14 18             	mov    %dl,(%eax,%ebx,1)

    // 设置子进程的返回值为0，表示fork成功
    proc->tf->tf_regs.reg_eax = 0;
c0109e99:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e9c:	8b 40 3c             	mov    0x3c(%eax),%eax
c0109e9f:	c7 40 1c 00 00 00 00 	movl   $0x0,0x1c(%eax)
    // 设置子进程的栈指针为指定的esp位置
    proc->tf->tf_esp = esp;
c0109ea6:	8b 45 08             	mov    0x8(%ebp),%eax
c0109ea9:	8b 40 3c             	mov    0x3c(%eax),%eax
c0109eac:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109eaf:	89 50 44             	mov    %edx,0x44(%eax)
     // 启用子进程的中断标志
    proc->tf->tf_eflags |= FL_IF;
c0109eb2:	8b 45 08             	mov    0x8(%ebp),%eax
c0109eb5:	8b 40 3c             	mov    0x3c(%eax),%eax
c0109eb8:	8b 50 40             	mov    0x40(%eax),%edx
c0109ebb:	8b 45 08             	mov    0x8(%ebp),%eax
c0109ebe:	8b 40 3c             	mov    0x3c(%eax),%eax
c0109ec1:	81 ca 00 02 00 00    	or     $0x200,%edx
c0109ec7:	89 50 40             	mov    %edx,0x40(%eax)

    // 设置子进程的初始指令指针为forkret函数的地址
    proc->context.eip = (uintptr_t)forkret;
c0109eca:	ba e9 99 10 c0       	mov    $0xc01099e9,%edx
c0109ecf:	8b 45 08             	mov    0x8(%ebp),%eax
c0109ed2:	89 50 1c             	mov    %edx,0x1c(%eax)
    // 设置子进程的栈指针为其陷阱帧的地址
    proc->context.esp = (uintptr_t)(proc->tf);
c0109ed5:	8b 45 08             	mov    0x8(%ebp),%eax
c0109ed8:	8b 40 3c             	mov    0x3c(%eax),%eax
c0109edb:	89 c2                	mov    %eax,%edx
c0109edd:	8b 45 08             	mov    0x8(%ebp),%eax
c0109ee0:	89 50 20             	mov    %edx,0x20(%eax)
}
c0109ee3:	90                   	nop
c0109ee4:	5b                   	pop    %ebx
c0109ee5:	5e                   	pop    %esi
c0109ee6:	5f                   	pop    %edi
c0109ee7:	5d                   	pop    %ebp
c0109ee8:	c3                   	ret    

c0109ee9 <do_fork>:
 * 
 * 此函数负责分配proc_struct、设置内核栈、复制或共享内存管理结构，
 * 复制线程上下文，将新进程插入到进程列表中，并将其设置为可运行状态
 */
int
do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
c0109ee9:	55                   	push   %ebp
c0109eea:	89 e5                	mov    %esp,%ebp
c0109eec:	83 ec 28             	sub    $0x28,%esp
    int ret = -E_NO_FREE_PROC;
c0109eef:	c7 45 f4 fb ff ff ff 	movl   $0xfffffffb,-0xc(%ebp)
    struct proc_struct *proc;
    // 检查系统中是否有足够的资源创建新进程
    if (nr_process >= MAX_PROCESS) {
c0109ef6:	a1 40 61 1a c0       	mov    0xc01a6140,%eax
c0109efb:	3d ff 0f 00 00       	cmp    $0xfff,%eax
c0109f00:	0f 8f e1 00 00 00    	jg     c0109fe7 <do_fork+0xfe>
        goto fork_out;
    }
    ret = -E_NO_MEM;
c0109f06:	c7 45 f4 fc ff ff ff 	movl   $0xfffffffc,-0xc(%ebp)
    //    4. call copy_thread to setup tf & context in proc_struct
    //    5. insert proc_struct into hash_list && proc_list
    //    6. call wakeup_proc to make the new child process RUNNABLE
    //    7. set ret vaule using child proc's pid
    //调用alloc_proc，首先获得一块用户信息块
    if((proc = alloc_proc()) == NULL){
c0109f0d:	e8 bc f6 ff ff       	call   c01095ce <alloc_proc>
c0109f12:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109f15:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0109f19:	0f 84 cb 00 00 00    	je     c0109fea <do_fork+0x101>
        goto fork_out;
    }

     // 设置新进程的父进程为当前进程，并确保当前进程的wait_state为0
    proc->parent = current;
c0109f1f:	8b 15 30 41 1a c0    	mov    0xc01a4130,%edx
c0109f25:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109f28:	89 50 14             	mov    %edx,0x14(%eax)
    assert(current->wait_state == 0);
c0109f2b:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c0109f30:	8b 40 6c             	mov    0x6c(%eax),%eax
c0109f33:	85 c0                	test   %eax,%eax
c0109f35:	74 24                	je     c0109f5b <do_fork+0x72>
c0109f37:	c7 44 24 0c b0 e0 10 	movl   $0xc010e0b0,0xc(%esp)
c0109f3e:	c0 
c0109f3f:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c0109f46:	c0 
c0109f47:	c7 44 24 04 17 02 00 	movl   $0x217,0x4(%esp)
c0109f4e:	00 
c0109f4f:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c0109f56:	e8 e0 6d ff ff       	call   c0100d3b <__panic>

    // 为新进程分配内核栈
    if (setup_kstack(proc) != 0) {
c0109f5b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109f5e:	89 04 24             	mov    %eax,(%esp)
c0109f61:	e8 43 fc ff ff       	call   c0109ba9 <setup_kstack>
c0109f66:	85 c0                	test   %eax,%eax
c0109f68:	0f 85 90 00 00 00    	jne    c0109ffe <do_fork+0x115>
        goto bad_fork_cleanup_proc;
    }
    // 根据clone_flags复制或共享内存管理结构
    if (copy_mm(clone_flags, proc) != 0) {
c0109f6e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109f71:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109f75:	8b 45 08             	mov    0x8(%ebp),%eax
c0109f78:	89 04 24             	mov    %eax,(%esp)
c0109f7b:	e8 62 fd ff ff       	call   c0109ce2 <copy_mm>
c0109f80:	85 c0                	test   %eax,%eax
c0109f82:	75 6c                	jne    c0109ff0 <do_fork+0x107>
        goto bad_fork_cleanup_kstack;
    }

    // 复制线程上下文到新进程
    copy_thread(proc, stack, tf);
c0109f84:	8b 45 10             	mov    0x10(%ebp),%eax
c0109f87:	89 44 24 08          	mov    %eax,0x8(%esp)
c0109f8b:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109f8e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109f92:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109f95:	89 04 24             	mov    %eax,(%esp)
c0109f98:	e8 66 fe ff ff       	call   c0109e03 <copy_thread>

    bool intr_flag;
    local_intr_save(intr_flag);
c0109f9d:	e8 de f3 ff ff       	call   c0109380 <__intr_save>
c0109fa2:	89 45 ec             	mov    %eax,-0x14(%ebp)
    {
        // 为新进程分配唯一的pid，并将其插入到进程哈希列表和进程列表中
        proc->pid = get_pid();
c0109fa5:	e8 cf f8 ff ff       	call   c0109879 <get_pid>
c0109faa:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0109fad:	89 42 04             	mov    %eax,0x4(%edx)
        hash_proc(proc);
c0109fb0:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109fb3:	89 04 24             	mov    %eax,(%esp)
c0109fb6:	e8 49 fa ff ff       	call   c0109a04 <hash_proc>
        set_links(proc);
c0109fbb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109fbe:	89 04 24             	mov    %eax,(%esp)
c0109fc1:	e8 84 f7 ff ff       	call   c010974a <set_links>

    }
    local_intr_restore(intr_flag);
c0109fc6:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109fc9:	89 04 24             	mov    %eax,(%esp)
c0109fcc:	e8 db f3 ff ff       	call   c01093ac <__intr_restore>

    // 将新进程设置为可运行状态
    wakeup_proc(proc);
c0109fd1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109fd4:	89 04 24             	mov    %eax,(%esp)
c0109fd7:	e8 19 10 00 00       	call   c010aff5 <wakeup_proc>

    // 设置返回值为新进程的pid
    ret = proc->pid;
c0109fdc:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109fdf:	8b 40 04             	mov    0x4(%eax),%eax
c0109fe2:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109fe5:	eb 04                	jmp    c0109feb <do_fork+0x102>
        goto fork_out;
c0109fe7:	90                   	nop
c0109fe8:	eb 01                	jmp    c0109feb <do_fork+0x102>
        goto fork_out;
c0109fea:	90                   	nop
	*    update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process
    */

	
fork_out:
    return ret;
c0109feb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109fee:	eb 1c                	jmp    c010a00c <do_fork+0x123>
        goto bad_fork_cleanup_kstack;
c0109ff0:	90                   	nop

bad_fork_cleanup_kstack:
 // 如果资源分配失败，释放已分配的内核栈
    put_kstack(proc);
c0109ff1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109ff4:	89 04 24             	mov    %eax,(%esp)
c0109ff7:	e8 eb fb ff ff       	call   c0109be7 <put_kstack>
c0109ffc:	eb 01                	jmp    c0109fff <do_fork+0x116>
        goto bad_fork_cleanup_proc;
c0109ffe:	90                   	nop
bad_fork_cleanup_proc:
// 释放proc_struct结构体
    kfree(proc);
c0109fff:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010a002:	89 04 24             	mov    %eax,(%esp)
c010a005:	e8 03 ad ff ff       	call   c0104d0d <kfree>
    goto fork_out;
c010a00a:	eb df                	jmp    c0109feb <do_fork+0x102>
}
c010a00c:	89 ec                	mov    %ebp,%esp
c010a00e:	5d                   	pop    %ebp
c010a00f:	c3                   	ret    

c010a010 <do_exit>:
 * @param error_code 进程退出码，表示进程退出的状态。
 * 
 * @return 该函数不会返回。
 */
int
do_exit(int error_code) {
c010a010:	55                   	push   %ebp
c010a011:	89 e5                	mov    %esp,%ebp
c010a013:	83 ec 28             	sub    $0x28,%esp
    // 检查当前进程是否为idle进程，如果是，则引发panic。
    if (current == idleproc) {
c010a016:	8b 15 30 41 1a c0    	mov    0xc01a4130,%edx
c010a01c:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010a021:	39 c2                	cmp    %eax,%edx
c010a023:	75 1c                	jne    c010a041 <do_exit+0x31>
        panic("idleproc exit.\n");
c010a025:	c7 44 24 08 de e0 10 	movl   $0xc010e0de,0x8(%esp)
c010a02c:	c0 
c010a02d:	c7 44 24 04 59 02 00 	movl   $0x259,0x4(%esp)
c010a034:	00 
c010a035:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a03c:	e8 fa 6c ff ff       	call   c0100d3b <__panic>
    }
    // 检查当前进程是否为init进程，如果是，则引发panic。
    if (current == initproc) {
c010a041:	8b 15 30 41 1a c0    	mov    0xc01a4130,%edx
c010a047:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010a04c:	39 c2                	cmp    %eax,%edx
c010a04e:	75 1c                	jne    c010a06c <do_exit+0x5c>
        panic("initproc exit.\n");
c010a050:	c7 44 24 08 ee e0 10 	movl   $0xc010e0ee,0x8(%esp)
c010a057:	c0 
c010a058:	c7 44 24 04 5d 02 00 	movl   $0x25d,0x4(%esp)
c010a05f:	00 
c010a060:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a067:	e8 cf 6c ff ff       	call   c0100d3b <__panic>
    }
    
    // 获取当前进程的内存管理结构。
    struct mm_struct *mm = current->mm;
c010a06c:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a071:	8b 40 18             	mov    0x18(%eax),%eax
c010a074:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 如果当前进程有内存管理结构，则进行清理。
    if (mm != NULL) {
c010a077:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010a07b:	74 4b                	je     c010a0c8 <do_exit+0xb8>
        // 加载引导页表，准备清理当前进程的页表。
        lcr3(boot_cr3);
c010a07d:	a1 a8 3f 1a c0       	mov    0xc01a3fa8,%eax
c010a082:	89 45 e8             	mov    %eax,-0x18(%ebp)
    asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory");
c010a085:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010a088:	0f 22 d8             	mov    %eax,%cr3
}
c010a08b:	90                   	nop
         // 如果内存管理结构的引用计数减到0，则释放相关资源。
        if (mm_count_dec(mm) == 0) {
c010a08c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a08f:	89 04 24             	mov    %eax,(%esp)
c010a092:	e8 df f4 ff ff       	call   c0109576 <mm_count_dec>
c010a097:	85 c0                	test   %eax,%eax
c010a099:	75 21                	jne    c010a0bc <do_exit+0xac>
            exit_mmap(mm);
c010a09b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a09e:	89 04 24             	mov    %eax,(%esp)
c010a0a1:	e8 07 e5 ff ff       	call   c01085ad <exit_mmap>
            put_pgdir(mm);
c010a0a6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a0a9:	89 04 24             	mov    %eax,(%esp)
c010a0ac:	e8 08 fc ff ff       	call   c0109cb9 <put_pgdir>
            mm_destroy(mm);
c010a0b1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a0b4:	89 04 24             	mov    %eax,(%esp)
c010a0b7:	e8 62 e2 ff ff       	call   c010831e <mm_destroy>
        }
         // 将当前进程的内存管理结构设置为NULL。
        current->mm = NULL;
c010a0bc:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a0c1:	c7 40 18 00 00 00 00 	movl   $0x0,0x18(%eax)
    }
    // 将当前进程的状态设置为僵尸状态，并保存退出码。
    current->state = PROC_ZOMBIE;
c010a0c8:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a0cd:	c7 00 03 00 00 00    	movl   $0x3,(%eax)
    current->exit_code = error_code;
c010a0d3:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a0d8:	8b 55 08             	mov    0x8(%ebp),%edx
c010a0db:	89 50 68             	mov    %edx,0x68(%eax)
    
     // 保存中断状态，并获取当前进程的父进程。
    bool intr_flag;
    struct proc_struct *proc;
    local_intr_save(intr_flag);
c010a0de:	e8 9d f2 ff ff       	call   c0109380 <__intr_save>
c010a0e3:	89 45 f0             	mov    %eax,-0x10(%ebp)
    {
        proc = current->parent;
c010a0e6:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a0eb:	8b 40 14             	mov    0x14(%eax),%eax
c010a0ee:	89 45 ec             	mov    %eax,-0x14(%ebp)
         // 如果父进程在等待子进程，则唤醒父进程。
        if (proc->wait_state == WT_CHILD) {
c010a0f1:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a0f4:	8b 40 6c             	mov    0x6c(%eax),%eax
c010a0f7:	3d 01 00 00 80       	cmp    $0x80000001,%eax
c010a0fc:	0f 85 96 00 00 00    	jne    c010a198 <do_exit+0x188>
            wakeup_proc(proc);
c010a102:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a105:	89 04 24             	mov    %eax,(%esp)
c010a108:	e8 e8 0e 00 00       	call   c010aff5 <wakeup_proc>
        }
          // 遍历当前进程的所有子进程，并将它们的父进程设置为init进程。
        while (current->cptr != NULL) {
c010a10d:	e9 86 00 00 00       	jmp    c010a198 <do_exit+0x188>
            proc = current->cptr;
c010a112:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a117:	8b 40 70             	mov    0x70(%eax),%eax
c010a11a:	89 45 ec             	mov    %eax,-0x14(%ebp)
            current->cptr = proc->optr;
c010a11d:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a122:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010a125:	8b 52 78             	mov    0x78(%edx),%edx
c010a128:	89 50 70             	mov    %edx,0x70(%eax)
    
            proc->yptr = NULL;
c010a12b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a12e:	c7 40 74 00 00 00 00 	movl   $0x0,0x74(%eax)
            if ((proc->optr = initproc->cptr) != NULL) {
c010a135:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010a13a:	8b 50 70             	mov    0x70(%eax),%edx
c010a13d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a140:	89 50 78             	mov    %edx,0x78(%eax)
c010a143:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a146:	8b 40 78             	mov    0x78(%eax),%eax
c010a149:	85 c0                	test   %eax,%eax
c010a14b:	74 0e                	je     c010a15b <do_exit+0x14b>
                initproc->cptr->yptr = proc;
c010a14d:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010a152:	8b 40 70             	mov    0x70(%eax),%eax
c010a155:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010a158:	89 50 74             	mov    %edx,0x74(%eax)
            }
            proc->parent = initproc;
c010a15b:	8b 15 2c 41 1a c0    	mov    0xc01a412c,%edx
c010a161:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a164:	89 50 14             	mov    %edx,0x14(%eax)
            initproc->cptr = proc;
c010a167:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010a16c:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010a16f:	89 50 70             	mov    %edx,0x70(%eax)
            // 如果子进程处于僵尸状态，并且init进程在等待子进程，则唤醒init进程。
            if (proc->state == PROC_ZOMBIE) {
c010a172:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a175:	8b 00                	mov    (%eax),%eax
c010a177:	83 f8 03             	cmp    $0x3,%eax
c010a17a:	75 1c                	jne    c010a198 <do_exit+0x188>
                if (initproc->wait_state == WT_CHILD) {
c010a17c:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010a181:	8b 40 6c             	mov    0x6c(%eax),%eax
c010a184:	3d 01 00 00 80       	cmp    $0x80000001,%eax
c010a189:	75 0d                	jne    c010a198 <do_exit+0x188>
                    wakeup_proc(initproc);
c010a18b:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010a190:	89 04 24             	mov    %eax,(%esp)
c010a193:	e8 5d 0e 00 00       	call   c010aff5 <wakeup_proc>
        while (current->cptr != NULL) {
c010a198:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a19d:	8b 40 70             	mov    0x70(%eax),%eax
c010a1a0:	85 c0                	test   %eax,%eax
c010a1a2:	0f 85 6a ff ff ff    	jne    c010a112 <do_exit+0x102>
                }
            }
        }
    }
     // 恢复中断状态。
    local_intr_restore(intr_flag);
c010a1a8:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010a1ab:	89 04 24             	mov    %eax,(%esp)
c010a1ae:	e8 f9 f1 ff ff       	call   c01093ac <__intr_restore>
     // 调度新的进程运行。
    schedule();
c010a1b3:	e8 c4 0e 00 00       	call   c010b07c <schedule>
    // 如果调度失败，引发panic。
    panic("do_exit will not return!! %d.\n", current->pid);
c010a1b8:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a1bd:	8b 40 04             	mov    0x4(%eax),%eax
c010a1c0:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010a1c4:	c7 44 24 08 00 e1 10 	movl   $0xc010e100,0x8(%esp)
c010a1cb:	c0 
c010a1cc:	c7 44 24 04 95 02 00 	movl   $0x295,0x4(%esp)
c010a1d3:	00 
c010a1d4:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a1db:	e8 5b 6b ff ff       	call   c0100d3b <__panic>

c010a1e0 <load_icode>:
 * @param binary 二进制程序的指针
 * @param size 二进制程序的大小
 * @return 成功返回 0，失败返回负的错误码
 */
static int
load_icode(unsigned char *binary, size_t size) {
c010a1e0:	55                   	push   %ebp
c010a1e1:	89 e5                	mov    %esp,%ebp
c010a1e3:	83 ec 78             	sub    $0x78,%esp
    // 检查当前进程是否已经有内存描述符，如果有则触发 panic
    if (current->mm != NULL) {
c010a1e6:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a1eb:	8b 40 18             	mov    0x18(%eax),%eax
c010a1ee:	85 c0                	test   %eax,%eax
c010a1f0:	74 1c                	je     c010a20e <load_icode+0x2e>
        panic("load_icode: current->mm must be empty.\n");
c010a1f2:	c7 44 24 08 20 e1 10 	movl   $0xc010e120,0x8(%esp)
c010a1f9:	c0 
c010a1fa:	c7 44 24 04 ae 02 00 	movl   $0x2ae,0x4(%esp)
c010a201:	00 
c010a202:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a209:	e8 2d 6b ff ff       	call   c0100d3b <__panic>
    }

    // 初始化返回值为 -E_NO_MEM
    int ret = -E_NO_MEM;
c010a20e:	c7 45 f4 fc ff ff ff 	movl   $0xfffffffc,-0xc(%ebp)
    struct mm_struct *mm;
    //(1) create a new mm for current process
    //(1) 为当前进程创建一个新的内存描述符 (mm_struct)
    if ((mm = mm_create()) == NULL) {
c010a215:	e8 9b dd ff ff       	call   c0107fb5 <mm_create>
c010a21a:	89 45 d0             	mov    %eax,-0x30(%ebp)
c010a21d:	83 7d d0 00          	cmpl   $0x0,-0x30(%ebp)
c010a221:	0f 84 0e 06 00 00    	je     c010a835 <load_icode+0x655>
        goto bad_mm;
    }
    //(2) create a new PDT, and mm->pgdir= kernel virtual addr of PDT
     // (2) 创建一个新的页目录表 (PDT)，并将 mm->pgdir 设置为内核虚拟地址的 PDT
    if (setup_pgdir(mm) != 0) {
c010a227:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a22a:	89 04 24             	mov    %eax,(%esp)
c010a22d:	e8 de f9 ff ff       	call   c0109c10 <setup_pgdir>
c010a232:	85 c0                	test   %eax,%eax
c010a234:	0f 85 ed 05 00 00    	jne    c010a827 <load_icode+0x647>
    //(3) copy TEXT/DATA section, build BSS parts in binary to memory space of process
    // (3) 将二进制程序的 TEXT/DATA 段复制到进程的内存空间，并构建 BSS 部分
    struct Page *page;
    //(3.1) get the file header of the bianry program (ELF format)
    // (3.1) 获取二进制程序的文件头 (ELF 格式)
    struct elfhdr *elf = (struct elfhdr *)binary;
c010a23a:	8b 45 08             	mov    0x8(%ebp),%eax
c010a23d:	89 45 cc             	mov    %eax,-0x34(%ebp)
    //(3.2) get the entry of the program section headers of the bianry program (ELF format)
    // (3.2) 获取二进制程序的程序段头表入口 (ELF 格式)
    struct proghdr *ph = (struct proghdr *)(binary + elf->e_phoff);
c010a240:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010a243:	8b 50 1c             	mov    0x1c(%eax),%edx
c010a246:	8b 45 08             	mov    0x8(%ebp),%eax
c010a249:	01 d0                	add    %edx,%eax
c010a24b:	89 45 ec             	mov    %eax,-0x14(%ebp)
    //(3.3) This program is valid?
    // (3.3) 检查程序是否有效
    if (elf->e_magic != ELF_MAGIC) {
c010a24e:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010a251:	8b 00                	mov    (%eax),%eax
c010a253:	3d 7f 45 4c 46       	cmp    $0x464c457f,%eax
c010a258:	74 0c                	je     c010a266 <load_icode+0x86>
        ret = -E_INVAL_ELF;
c010a25a:	c7 45 f4 f8 ff ff ff 	movl   $0xfffffff8,-0xc(%ebp)
        goto bad_elf_cleanup_pgdir;
c010a261:	e9 b4 05 00 00       	jmp    c010a81a <load_icode+0x63a>
    }

    uint32_t vm_flags, perm;
    struct proghdr *ph_end = ph + elf->e_phnum;
c010a266:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010a269:	0f b7 40 2c          	movzwl 0x2c(%eax),%eax
c010a26d:	c1 e0 05             	shl    $0x5,%eax
c010a270:	89 c2                	mov    %eax,%edx
c010a272:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a275:	01 d0                	add    %edx,%eax
c010a277:	89 45 c8             	mov    %eax,-0x38(%ebp)
    for (; ph < ph_end; ph ++) {
c010a27a:	e9 01 03 00 00       	jmp    c010a580 <load_icode+0x3a0>
    //(3.4) find every program section headers
    // (3.4) 查找每一个程序段头
        if (ph->p_type != ELF_PT_LOAD) {
c010a27f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a282:	8b 00                	mov    (%eax),%eax
c010a284:	83 f8 01             	cmp    $0x1,%eax
c010a287:	0f 85 e8 02 00 00    	jne    c010a575 <load_icode+0x395>
            continue ;
        }
        if (ph->p_filesz > ph->p_memsz) {
c010a28d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a290:	8b 50 10             	mov    0x10(%eax),%edx
c010a293:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a296:	8b 40 14             	mov    0x14(%eax),%eax
c010a299:	39 c2                	cmp    %eax,%edx
c010a29b:	76 0c                	jbe    c010a2a9 <load_icode+0xc9>
            ret = -E_INVAL_ELF;
c010a29d:	c7 45 f4 f8 ff ff ff 	movl   $0xfffffff8,-0xc(%ebp)
            goto bad_cleanup_mmap;
c010a2a4:	e9 66 05 00 00       	jmp    c010a80f <load_icode+0x62f>
        }
        if (ph->p_filesz == 0) {
c010a2a9:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a2ac:	8b 40 10             	mov    0x10(%eax),%eax
c010a2af:	85 c0                	test   %eax,%eax
c010a2b1:	0f 84 c1 02 00 00    	je     c010a578 <load_icode+0x398>
            continue ;
        }
    //(3.5) call mm_map fun to setup the new vma ( ph->p_va, ph->p_memsz)
     // (3.5) 调用 mm_map 函数设置新的 VMA (ph->p_va, ph->p_memsz)
        vm_flags = 0, perm = PTE_U;
c010a2b7:	c7 45 e8 00 00 00 00 	movl   $0x0,-0x18(%ebp)
c010a2be:	c7 45 e4 04 00 00 00 	movl   $0x4,-0x1c(%ebp)
        if (ph->p_flags & ELF_PF_X) vm_flags |= VM_EXEC;
c010a2c5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a2c8:	8b 40 18             	mov    0x18(%eax),%eax
c010a2cb:	83 e0 01             	and    $0x1,%eax
c010a2ce:	85 c0                	test   %eax,%eax
c010a2d0:	74 04                	je     c010a2d6 <load_icode+0xf6>
c010a2d2:	83 4d e8 04          	orl    $0x4,-0x18(%ebp)
        if (ph->p_flags & ELF_PF_W) vm_flags |= VM_WRITE;
c010a2d6:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a2d9:	8b 40 18             	mov    0x18(%eax),%eax
c010a2dc:	83 e0 02             	and    $0x2,%eax
c010a2df:	85 c0                	test   %eax,%eax
c010a2e1:	74 04                	je     c010a2e7 <load_icode+0x107>
c010a2e3:	83 4d e8 02          	orl    $0x2,-0x18(%ebp)
        if (ph->p_flags & ELF_PF_R) vm_flags |= VM_READ;
c010a2e7:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a2ea:	8b 40 18             	mov    0x18(%eax),%eax
c010a2ed:	83 e0 04             	and    $0x4,%eax
c010a2f0:	85 c0                	test   %eax,%eax
c010a2f2:	74 04                	je     c010a2f8 <load_icode+0x118>
c010a2f4:	83 4d e8 01          	orl    $0x1,-0x18(%ebp)
        if (vm_flags & VM_WRITE) perm |= PTE_W;
c010a2f8:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010a2fb:	83 e0 02             	and    $0x2,%eax
c010a2fe:	85 c0                	test   %eax,%eax
c010a300:	74 04                	je     c010a306 <load_icode+0x126>
c010a302:	83 4d e4 02          	orl    $0x2,-0x1c(%ebp)
        if ((ret = mm_map(mm, ph->p_va, ph->p_memsz, vm_flags, NULL)) != 0) {
c010a306:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a309:	8b 50 14             	mov    0x14(%eax),%edx
c010a30c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a30f:	8b 40 08             	mov    0x8(%eax),%eax
c010a312:	c7 44 24 10 00 00 00 	movl   $0x0,0x10(%esp)
c010a319:	00 
c010a31a:	8b 4d e8             	mov    -0x18(%ebp),%ecx
c010a31d:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c010a321:	89 54 24 08          	mov    %edx,0x8(%esp)
c010a325:	89 44 24 04          	mov    %eax,0x4(%esp)
c010a329:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a32c:	89 04 24             	mov    %eax,(%esp)
c010a32f:	e8 5e e0 ff ff       	call   c0108392 <mm_map>
c010a334:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010a337:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010a33b:	0f 85 c4 04 00 00    	jne    c010a805 <load_icode+0x625>
            goto bad_cleanup_mmap;
        }
        unsigned char *from = binary + ph->p_offset;
c010a341:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a344:	8b 50 04             	mov    0x4(%eax),%edx
c010a347:	8b 45 08             	mov    0x8(%ebp),%eax
c010a34a:	01 d0                	add    %edx,%eax
c010a34c:	89 45 e0             	mov    %eax,-0x20(%ebp)
        size_t off, size;
        uintptr_t start = ph->p_va, end, la = ROUNDDOWN(start, PGSIZE);
c010a34f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a352:	8b 40 08             	mov    0x8(%eax),%eax
c010a355:	89 45 d8             	mov    %eax,-0x28(%ebp)
c010a358:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a35b:	89 45 b8             	mov    %eax,-0x48(%ebp)
c010a35e:	8b 45 b8             	mov    -0x48(%ebp),%eax
c010a361:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010a366:	89 45 d4             	mov    %eax,-0x2c(%ebp)

        ret = -E_NO_MEM;
c010a369:	c7 45 f4 fc ff ff ff 	movl   $0xfffffffc,-0xc(%ebp)

     //(3.6) alloc memory, and  copy the contents of every program section (from, from+end) to process's memory (la, la+end)
      // (3.6) 分配内存，并将每个程序段的内容 (from, from+end) 复制到进程的内存 (la, la+end)
        end = ph->p_va + ph->p_filesz;
c010a370:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a373:	8b 50 08             	mov    0x8(%eax),%edx
c010a376:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a379:	8b 40 10             	mov    0x10(%eax),%eax
c010a37c:	01 d0                	add    %edx,%eax
c010a37e:	89 45 b4             	mov    %eax,-0x4c(%ebp)
     //(3.6.1) copy TEXT/DATA section of bianry program
     // (3.6.1) 复制二进制程序的 TEXT/DATA 段
        while (start < end) {
c010a381:	e9 87 00 00 00       	jmp    c010a40d <load_icode+0x22d>
            if ((page = pgdir_alloc_page(mm->pgdir, la, perm)) == NULL) {
c010a386:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a389:	8b 40 0c             	mov    0xc(%eax),%eax
c010a38c:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010a38f:	89 54 24 08          	mov    %edx,0x8(%esp)
c010a393:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010a396:	89 54 24 04          	mov    %edx,0x4(%esp)
c010a39a:	89 04 24             	mov    %eax,(%esp)
c010a39d:	e8 1b bc ff ff       	call   c0105fbd <pgdir_alloc_page>
c010a3a2:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010a3a5:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010a3a9:	0f 84 59 04 00 00    	je     c010a808 <load_icode+0x628>
                goto bad_cleanup_mmap;
            }
            off = start - la, size = PGSIZE - off, la += PGSIZE;
c010a3af:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a3b2:	2b 45 d4             	sub    -0x2c(%ebp),%eax
c010a3b5:	89 45 b0             	mov    %eax,-0x50(%ebp)
c010a3b8:	b8 00 10 00 00       	mov    $0x1000,%eax
c010a3bd:	2b 45 b0             	sub    -0x50(%ebp),%eax
c010a3c0:	89 45 dc             	mov    %eax,-0x24(%ebp)
c010a3c3:	81 45 d4 00 10 00 00 	addl   $0x1000,-0x2c(%ebp)
            if (end < la) {
c010a3ca:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010a3cd:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c010a3d0:	73 09                	jae    c010a3db <load_icode+0x1fb>
                size -= la - end;
c010a3d2:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010a3d5:	2b 45 d4             	sub    -0x2c(%ebp),%eax
c010a3d8:	01 45 dc             	add    %eax,-0x24(%ebp)
            }
            memcpy(page2kva(page) + off, from, size);
c010a3db:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010a3de:	89 04 24             	mov    %eax,(%esp)
c010a3e1:	e8 d4 f0 ff ff       	call   c01094ba <page2kva>
c010a3e6:	8b 55 b0             	mov    -0x50(%ebp),%edx
c010a3e9:	01 c2                	add    %eax,%edx
c010a3eb:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010a3ee:	89 44 24 08          	mov    %eax,0x8(%esp)
c010a3f2:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010a3f5:	89 44 24 04          	mov    %eax,0x4(%esp)
c010a3f9:	89 14 24             	mov    %edx,(%esp)
c010a3fc:	e8 d5 1a 00 00       	call   c010bed6 <memcpy>
            start += size, from += size;
c010a401:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010a404:	01 45 d8             	add    %eax,-0x28(%ebp)
c010a407:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010a40a:	01 45 e0             	add    %eax,-0x20(%ebp)
        while (start < end) {
c010a40d:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a410:	3b 45 b4             	cmp    -0x4c(%ebp),%eax
c010a413:	0f 82 6d ff ff ff    	jb     c010a386 <load_icode+0x1a6>
        }

      //(3.6.2) build BSS section of binary program
      // (3.6.2) 构建二进制程序的 BSS 段
        end = ph->p_va + ph->p_memsz;
c010a419:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a41c:	8b 50 08             	mov    0x8(%eax),%edx
c010a41f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a422:	8b 40 14             	mov    0x14(%eax),%eax
c010a425:	01 d0                	add    %edx,%eax
c010a427:	89 45 b4             	mov    %eax,-0x4c(%ebp)
        if (start < la) {
c010a42a:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a42d:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c010a430:	0f 83 31 01 00 00    	jae    c010a567 <load_icode+0x387>
            /* ph->p_memsz == ph->p_filesz */
            if (start == end) {
c010a436:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a439:	3b 45 b4             	cmp    -0x4c(%ebp),%eax
c010a43c:	0f 84 39 01 00 00    	je     c010a57b <load_icode+0x39b>
                continue ;
            }
            off = start + PGSIZE - la, size = PGSIZE - off;
c010a442:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a445:	2b 45 d4             	sub    -0x2c(%ebp),%eax
c010a448:	05 00 10 00 00       	add    $0x1000,%eax
c010a44d:	89 45 b0             	mov    %eax,-0x50(%ebp)
c010a450:	b8 00 10 00 00       	mov    $0x1000,%eax
c010a455:	2b 45 b0             	sub    -0x50(%ebp),%eax
c010a458:	89 45 dc             	mov    %eax,-0x24(%ebp)
            if (end < la) {
c010a45b:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010a45e:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c010a461:	73 09                	jae    c010a46c <load_icode+0x28c>
                size -= la - end;
c010a463:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010a466:	2b 45 d4             	sub    -0x2c(%ebp),%eax
c010a469:	01 45 dc             	add    %eax,-0x24(%ebp)
            }
            memset(page2kva(page) + off, 0, size);
c010a46c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010a46f:	89 04 24             	mov    %eax,(%esp)
c010a472:	e8 43 f0 ff ff       	call   c01094ba <page2kva>
c010a477:	8b 55 b0             	mov    -0x50(%ebp),%edx
c010a47a:	01 c2                	add    %eax,%edx
c010a47c:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010a47f:	89 44 24 08          	mov    %eax,0x8(%esp)
c010a483:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010a48a:	00 
c010a48b:	89 14 24             	mov    %edx,(%esp)
c010a48e:	e8 5e 19 00 00       	call   c010bdf1 <memset>
            start += size;
c010a493:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010a496:	01 45 d8             	add    %eax,-0x28(%ebp)
            assert((end < la && start == end) || (end >= la && start == la));
c010a499:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010a49c:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c010a49f:	73 0c                	jae    c010a4ad <load_icode+0x2cd>
c010a4a1:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a4a4:	3b 45 b4             	cmp    -0x4c(%ebp),%eax
c010a4a7:	0f 84 ba 00 00 00    	je     c010a567 <load_icode+0x387>
c010a4ad:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010a4b0:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c010a4b3:	72 0c                	jb     c010a4c1 <load_icode+0x2e1>
c010a4b5:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a4b8:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c010a4bb:	0f 84 a6 00 00 00    	je     c010a567 <load_icode+0x387>
c010a4c1:	c7 44 24 0c 48 e1 10 	movl   $0xc010e148,0xc(%esp)
c010a4c8:	c0 
c010a4c9:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010a4d0:	c0 
c010a4d1:	c7 44 24 04 0c 03 00 	movl   $0x30c,0x4(%esp)
c010a4d8:	00 
c010a4d9:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a4e0:	e8 56 68 ff ff       	call   c0100d3b <__panic>
        }
        while (start < end) {
            if ((page = pgdir_alloc_page(mm->pgdir, la, perm)) == NULL) {
c010a4e5:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a4e8:	8b 40 0c             	mov    0xc(%eax),%eax
c010a4eb:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010a4ee:	89 54 24 08          	mov    %edx,0x8(%esp)
c010a4f2:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010a4f5:	89 54 24 04          	mov    %edx,0x4(%esp)
c010a4f9:	89 04 24             	mov    %eax,(%esp)
c010a4fc:	e8 bc ba ff ff       	call   c0105fbd <pgdir_alloc_page>
c010a501:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010a504:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010a508:	0f 84 fd 02 00 00    	je     c010a80b <load_icode+0x62b>
                goto bad_cleanup_mmap;
            }
            off = start - la, size = PGSIZE - off, la += PGSIZE;
c010a50e:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a511:	2b 45 d4             	sub    -0x2c(%ebp),%eax
c010a514:	89 45 b0             	mov    %eax,-0x50(%ebp)
c010a517:	b8 00 10 00 00       	mov    $0x1000,%eax
c010a51c:	2b 45 b0             	sub    -0x50(%ebp),%eax
c010a51f:	89 45 dc             	mov    %eax,-0x24(%ebp)
c010a522:	81 45 d4 00 10 00 00 	addl   $0x1000,-0x2c(%ebp)
            if (end < la) {
c010a529:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010a52c:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c010a52f:	73 09                	jae    c010a53a <load_icode+0x35a>
                size -= la - end;
c010a531:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010a534:	2b 45 d4             	sub    -0x2c(%ebp),%eax
c010a537:	01 45 dc             	add    %eax,-0x24(%ebp)
            }
            memset(page2kva(page) + off, 0, size);
c010a53a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010a53d:	89 04 24             	mov    %eax,(%esp)
c010a540:	e8 75 ef ff ff       	call   c01094ba <page2kva>
c010a545:	8b 55 b0             	mov    -0x50(%ebp),%edx
c010a548:	01 c2                	add    %eax,%edx
c010a54a:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010a54d:	89 44 24 08          	mov    %eax,0x8(%esp)
c010a551:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010a558:	00 
c010a559:	89 14 24             	mov    %edx,(%esp)
c010a55c:	e8 90 18 00 00       	call   c010bdf1 <memset>
            start += size;
c010a561:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010a564:	01 45 d8             	add    %eax,-0x28(%ebp)
        while (start < end) {
c010a567:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010a56a:	3b 45 b4             	cmp    -0x4c(%ebp),%eax
c010a56d:	0f 82 72 ff ff ff    	jb     c010a4e5 <load_icode+0x305>
c010a573:	eb 07                	jmp    c010a57c <load_icode+0x39c>
            continue ;
c010a575:	90                   	nop
c010a576:	eb 04                	jmp    c010a57c <load_icode+0x39c>
            continue ;
c010a578:	90                   	nop
c010a579:	eb 01                	jmp    c010a57c <load_icode+0x39c>
                continue ;
c010a57b:	90                   	nop
    for (; ph < ph_end; ph ++) {
c010a57c:	83 45 ec 20          	addl   $0x20,-0x14(%ebp)
c010a580:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a583:	3b 45 c8             	cmp    -0x38(%ebp),%eax
c010a586:	0f 82 f3 fc ff ff    	jb     c010a27f <load_icode+0x9f>
        }
    }
    //(4) build user stack memory
    // (4) 构建用户栈内存
    vm_flags = VM_READ | VM_WRITE | VM_STACK;
c010a58c:	c7 45 e8 0b 00 00 00 	movl   $0xb,-0x18(%ebp)
    if ((ret = mm_map(mm, USTACKTOP - USTACKSIZE, USTACKSIZE, vm_flags, NULL)) != 0) {
c010a593:	c7 44 24 10 00 00 00 	movl   $0x0,0x10(%esp)
c010a59a:	00 
c010a59b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010a59e:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010a5a2:	c7 44 24 08 00 00 10 	movl   $0x100000,0x8(%esp)
c010a5a9:	00 
c010a5aa:	c7 44 24 04 00 00 f0 	movl   $0xaff00000,0x4(%esp)
c010a5b1:	af 
c010a5b2:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a5b5:	89 04 24             	mov    %eax,(%esp)
c010a5b8:	e8 d5 dd ff ff       	call   c0108392 <mm_map>
c010a5bd:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010a5c0:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010a5c4:	0f 85 44 02 00 00    	jne    c010a80e <load_icode+0x62e>
        goto bad_cleanup_mmap;
    }
    assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-PGSIZE , PTE_USER) != NULL);
c010a5ca:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a5cd:	8b 40 0c             	mov    0xc(%eax),%eax
c010a5d0:	c7 44 24 08 07 00 00 	movl   $0x7,0x8(%esp)
c010a5d7:	00 
c010a5d8:	c7 44 24 04 00 f0 ff 	movl   $0xaffff000,0x4(%esp)
c010a5df:	af 
c010a5e0:	89 04 24             	mov    %eax,(%esp)
c010a5e3:	e8 d5 b9 ff ff       	call   c0105fbd <pgdir_alloc_page>
c010a5e8:	85 c0                	test   %eax,%eax
c010a5ea:	75 24                	jne    c010a610 <load_icode+0x430>
c010a5ec:	c7 44 24 0c 84 e1 10 	movl   $0xc010e184,0xc(%esp)
c010a5f3:	c0 
c010a5f4:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010a5fb:	c0 
c010a5fc:	c7 44 24 04 20 03 00 	movl   $0x320,0x4(%esp)
c010a603:	00 
c010a604:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a60b:	e8 2b 67 ff ff       	call   c0100d3b <__panic>
    assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-2*PGSIZE , PTE_USER) != NULL);
c010a610:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a613:	8b 40 0c             	mov    0xc(%eax),%eax
c010a616:	c7 44 24 08 07 00 00 	movl   $0x7,0x8(%esp)
c010a61d:	00 
c010a61e:	c7 44 24 04 00 e0 ff 	movl   $0xafffe000,0x4(%esp)
c010a625:	af 
c010a626:	89 04 24             	mov    %eax,(%esp)
c010a629:	e8 8f b9 ff ff       	call   c0105fbd <pgdir_alloc_page>
c010a62e:	85 c0                	test   %eax,%eax
c010a630:	75 24                	jne    c010a656 <load_icode+0x476>
c010a632:	c7 44 24 0c c8 e1 10 	movl   $0xc010e1c8,0xc(%esp)
c010a639:	c0 
c010a63a:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010a641:	c0 
c010a642:	c7 44 24 04 21 03 00 	movl   $0x321,0x4(%esp)
c010a649:	00 
c010a64a:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a651:	e8 e5 66 ff ff       	call   c0100d3b <__panic>
    assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-3*PGSIZE , PTE_USER) != NULL);
c010a656:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a659:	8b 40 0c             	mov    0xc(%eax),%eax
c010a65c:	c7 44 24 08 07 00 00 	movl   $0x7,0x8(%esp)
c010a663:	00 
c010a664:	c7 44 24 04 00 d0 ff 	movl   $0xafffd000,0x4(%esp)
c010a66b:	af 
c010a66c:	89 04 24             	mov    %eax,(%esp)
c010a66f:	e8 49 b9 ff ff       	call   c0105fbd <pgdir_alloc_page>
c010a674:	85 c0                	test   %eax,%eax
c010a676:	75 24                	jne    c010a69c <load_icode+0x4bc>
c010a678:	c7 44 24 0c 0c e2 10 	movl   $0xc010e20c,0xc(%esp)
c010a67f:	c0 
c010a680:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010a687:	c0 
c010a688:	c7 44 24 04 22 03 00 	movl   $0x322,0x4(%esp)
c010a68f:	00 
c010a690:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a697:	e8 9f 66 ff ff       	call   c0100d3b <__panic>
    assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-4*PGSIZE , PTE_USER) != NULL);
c010a69c:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a69f:	8b 40 0c             	mov    0xc(%eax),%eax
c010a6a2:	c7 44 24 08 07 00 00 	movl   $0x7,0x8(%esp)
c010a6a9:	00 
c010a6aa:	c7 44 24 04 00 c0 ff 	movl   $0xafffc000,0x4(%esp)
c010a6b1:	af 
c010a6b2:	89 04 24             	mov    %eax,(%esp)
c010a6b5:	e8 03 b9 ff ff       	call   c0105fbd <pgdir_alloc_page>
c010a6ba:	85 c0                	test   %eax,%eax
c010a6bc:	75 24                	jne    c010a6e2 <load_icode+0x502>
c010a6be:	c7 44 24 0c 50 e2 10 	movl   $0xc010e250,0xc(%esp)
c010a6c5:	c0 
c010a6c6:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010a6cd:	c0 
c010a6ce:	c7 44 24 04 23 03 00 	movl   $0x323,0x4(%esp)
c010a6d5:	00 
c010a6d6:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a6dd:	e8 59 66 ff ff       	call   c0100d3b <__panic>
    
    //(5) set current process's mm, sr3, and set CR3 reg = physical addr of Page Directory
    // (5) 设置当前进程的 mm、sr3，并将 CR3 寄存器设置为页目录的物理地址
    mm_count_inc(mm);
c010a6e2:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a6e5:	89 04 24             	mov    %eax,(%esp)
c010a6e8:	e8 6f ee ff ff       	call   c010955c <mm_count_inc>
    current->mm = mm;
c010a6ed:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a6f2:	8b 55 d0             	mov    -0x30(%ebp),%edx
c010a6f5:	89 50 18             	mov    %edx,0x18(%eax)
    current->cr3 = PADDR(mm->pgdir);
c010a6f8:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a6fb:	8b 40 0c             	mov    0xc(%eax),%eax
c010a6fe:	89 45 c4             	mov    %eax,-0x3c(%ebp)
c010a701:	81 7d c4 ff ff ff bf 	cmpl   $0xbfffffff,-0x3c(%ebp)
c010a708:	77 23                	ja     c010a72d <load_icode+0x54d>
c010a70a:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c010a70d:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010a711:	c7 44 24 08 78 e0 10 	movl   $0xc010e078,0x8(%esp)
c010a718:	c0 
c010a719:	c7 44 24 04 29 03 00 	movl   $0x329,0x4(%esp)
c010a720:	00 
c010a721:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a728:	e8 0e 66 ff ff       	call   c0100d3b <__panic>
c010a72d:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c010a730:	8d 90 00 00 00 40    	lea    0x40000000(%eax),%edx
c010a736:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a73b:	89 50 40             	mov    %edx,0x40(%eax)
    lcr3(PADDR(mm->pgdir));
c010a73e:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a741:	8b 40 0c             	mov    0xc(%eax),%eax
c010a744:	89 45 c0             	mov    %eax,-0x40(%ebp)
c010a747:	81 7d c0 ff ff ff bf 	cmpl   $0xbfffffff,-0x40(%ebp)
c010a74e:	77 23                	ja     c010a773 <load_icode+0x593>
c010a750:	8b 45 c0             	mov    -0x40(%ebp),%eax
c010a753:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010a757:	c7 44 24 08 78 e0 10 	movl   $0xc010e078,0x8(%esp)
c010a75e:	c0 
c010a75f:	c7 44 24 04 2a 03 00 	movl   $0x32a,0x4(%esp)
c010a766:	00 
c010a767:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a76e:	e8 c8 65 ff ff       	call   c0100d3b <__panic>
c010a773:	8b 45 c0             	mov    -0x40(%ebp),%eax
c010a776:	05 00 00 00 40       	add    $0x40000000,%eax
c010a77b:	89 45 ac             	mov    %eax,-0x54(%ebp)
    asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory");
c010a77e:	8b 45 ac             	mov    -0x54(%ebp),%eax
c010a781:	0f 22 d8             	mov    %eax,%cr3
}
c010a784:	90                   	nop

    //(6) setup trapframe for user environment
     // (6) 为用户环境设置陷阱帧 (trapframe)
    struct trapframe *tf = current->tf;
c010a785:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a78a:	8b 40 3c             	mov    0x3c(%eax),%eax
c010a78d:	89 45 bc             	mov    %eax,-0x44(%ebp)
    memset(tf, 0, sizeof(struct trapframe));
c010a790:	c7 44 24 08 4c 00 00 	movl   $0x4c,0x8(%esp)
c010a797:	00 
c010a798:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010a79f:	00 
c010a7a0:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7a3:	89 04 24             	mov    %eax,(%esp)
c010a7a6:	e8 46 16 00 00       	call   c010bdf1 <memset>
     *          tf_ds=tf_es=tf_ss should be USER_DS segment
     *          tf_esp should be the top addr of user stack (USTACKTOP)
     *          tf_eip should be the entry point of this binary program (elf->e_entry)
     *          tf_eflags should be set to enable computer to produce Interrupt
     */
    tf->tf_cs = USER_CS;
c010a7ab:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7ae:	66 c7 40 3c 1b 00    	movw   $0x1b,0x3c(%eax)
    tf->tf_ds = tf->tf_es = tf->tf_ss = USER_DS;
c010a7b4:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7b7:	66 c7 40 48 23 00    	movw   $0x23,0x48(%eax)
c010a7bd:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7c0:	0f b7 50 48          	movzwl 0x48(%eax),%edx
c010a7c4:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7c7:	66 89 50 28          	mov    %dx,0x28(%eax)
c010a7cb:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7ce:	0f b7 50 28          	movzwl 0x28(%eax),%edx
c010a7d2:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7d5:	66 89 50 2c          	mov    %dx,0x2c(%eax)
    tf->tf_esp = USTACKTOP;
c010a7d9:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7dc:	c7 40 44 00 00 00 b0 	movl   $0xb0000000,0x44(%eax)
    tf->tf_eip = elf->e_entry;
c010a7e3:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010a7e6:	8b 50 18             	mov    0x18(%eax),%edx
c010a7e9:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7ec:	89 50 38             	mov    %edx,0x38(%eax)
    tf->tf_eflags = FL_IF;
c010a7ef:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010a7f2:	c7 40 40 00 02 00 00 	movl   $0x200,0x40(%eax)
    ret = 0;
c010a7f9:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
out:
    return ret;
c010a800:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a803:	eb 33                	jmp    c010a838 <load_icode+0x658>
            goto bad_cleanup_mmap;
c010a805:	90                   	nop
c010a806:	eb 07                	jmp    c010a80f <load_icode+0x62f>
                goto bad_cleanup_mmap;
c010a808:	90                   	nop
c010a809:	eb 04                	jmp    c010a80f <load_icode+0x62f>
                goto bad_cleanup_mmap;
c010a80b:	90                   	nop
c010a80c:	eb 01                	jmp    c010a80f <load_icode+0x62f>
        goto bad_cleanup_mmap;
c010a80e:	90                   	nop
bad_cleanup_mmap:
    exit_mmap(mm);
c010a80f:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a812:	89 04 24             	mov    %eax,(%esp)
c010a815:	e8 93 dd ff ff       	call   c01085ad <exit_mmap>
bad_elf_cleanup_pgdir:
    put_pgdir(mm);
c010a81a:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a81d:	89 04 24             	mov    %eax,(%esp)
c010a820:	e8 94 f4 ff ff       	call   c0109cb9 <put_pgdir>
c010a825:	eb 01                	jmp    c010a828 <load_icode+0x648>
        goto bad_pgdir_cleanup_mm;
c010a827:	90                   	nop
bad_pgdir_cleanup_mm:
    mm_destroy(mm);
c010a828:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010a82b:	89 04 24             	mov    %eax,(%esp)
c010a82e:	e8 eb da ff ff       	call   c010831e <mm_destroy>
bad_mm:
    goto out;
c010a833:	eb cb                	jmp    c010a800 <load_icode+0x620>
        goto bad_mm;
c010a835:	90                   	nop
    goto out;
c010a836:	eb c8                	jmp    c010a800 <load_icode+0x620>
}
c010a838:	89 ec                	mov    %ebp,%esp
c010a83a:	5d                   	pop    %ebp
c010a83b:	c3                   	ret    

c010a83c <do_execve>:
 * 如果加载过程中发生错误，函数将终止当前进程
 * 
 * @return 成功时返回0，失败时返回错误码
 */
int
do_execve(const char *name, size_t len, unsigned char *binary, size_t size) {
c010a83c:	55                   	push   %ebp
c010a83d:	89 e5                	mov    %esp,%ebp
c010a83f:	83 ec 38             	sub    $0x38,%esp
    // 获取当前进程的内存管理结构
    struct mm_struct *mm = current->mm;
c010a842:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a847:	8b 40 18             	mov    0x18(%eax),%eax
c010a84a:	89 45 f4             	mov    %eax,-0xc(%ebp)
    
    // 检查程序名称是否在用户空间中有效
    if (!user_mem_check(mm, (uintptr_t)name, len, 0)) {
c010a84d:	8b 45 08             	mov    0x8(%ebp),%eax
c010a850:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c010a857:	00 
c010a858:	8b 55 0c             	mov    0xc(%ebp),%edx
c010a85b:	89 54 24 08          	mov    %edx,0x8(%esp)
c010a85f:	89 44 24 04          	mov    %eax,0x4(%esp)
c010a863:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a866:	89 04 24             	mov    %eax,(%esp)
c010a869:	e8 ec e7 ff ff       	call   c010905a <user_mem_check>
c010a86e:	85 c0                	test   %eax,%eax
c010a870:	75 0a                	jne    c010a87c <do_execve+0x40>
        return -E_INVAL;
c010a872:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
c010a877:	e9 f7 00 00 00       	jmp    c010a973 <do_execve+0x137>
    }

    // 如果程序名称过长，截断到最大长度
    if (len > PROC_NAME_LEN) {
c010a87c:	83 7d 0c 0f          	cmpl   $0xf,0xc(%ebp)
c010a880:	76 07                	jbe    c010a889 <do_execve+0x4d>
        len = PROC_NAME_LEN;
c010a882:	c7 45 0c 0f 00 00 00 	movl   $0xf,0xc(%ebp)
    }

     // 准备一个本地缓冲区，用于存储程序名称
    char local_name[PROC_NAME_LEN + 1];
    memset(local_name, 0, sizeof(local_name));
c010a889:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
c010a890:	00 
c010a891:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010a898:	00 
c010a899:	8d 45 dc             	lea    -0x24(%ebp),%eax
c010a89c:	89 04 24             	mov    %eax,(%esp)
c010a89f:	e8 4d 15 00 00       	call   c010bdf1 <memset>
    memcpy(local_name, name, len);
c010a8a4:	8b 45 0c             	mov    0xc(%ebp),%eax
c010a8a7:	89 44 24 08          	mov    %eax,0x8(%esp)
c010a8ab:	8b 45 08             	mov    0x8(%ebp),%eax
c010a8ae:	89 44 24 04          	mov    %eax,0x4(%esp)
c010a8b2:	8d 45 dc             	lea    -0x24(%ebp),%eax
c010a8b5:	89 04 24             	mov    %eax,(%esp)
c010a8b8:	e8 19 16 00 00       	call   c010bed6 <memcpy>

    // 如果当前进程已有内存管理结构，进行清理
    if (mm != NULL) {
c010a8bd:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010a8c1:	74 4b                	je     c010a90e <do_execve+0xd2>
        // 切换到引导页表，准备清理当前进程的地址空间
        lcr3(boot_cr3);
c010a8c3:	a1 a8 3f 1a c0       	mov    0xc01a3fa8,%eax
c010a8c8:	89 45 ec             	mov    %eax,-0x14(%ebp)
    asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory");
c010a8cb:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a8ce:	0f 22 d8             	mov    %eax,%cr3
}
c010a8d1:	90                   	nop

        // 减少内存管理结构的引用计数，如果为0则进行清理
        if (mm_count_dec(mm) == 0) {
c010a8d2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a8d5:	89 04 24             	mov    %eax,(%esp)
c010a8d8:	e8 99 ec ff ff       	call   c0109576 <mm_count_dec>
c010a8dd:	85 c0                	test   %eax,%eax
c010a8df:	75 21                	jne    c010a902 <do_execve+0xc6>
            exit_mmap(mm);
c010a8e1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a8e4:	89 04 24             	mov    %eax,(%esp)
c010a8e7:	e8 c1 dc ff ff       	call   c01085ad <exit_mmap>
            put_pgdir(mm);
c010a8ec:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a8ef:	89 04 24             	mov    %eax,(%esp)
c010a8f2:	e8 c2 f3 ff ff       	call   c0109cb9 <put_pgdir>
            mm_destroy(mm);
c010a8f7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a8fa:	89 04 24             	mov    %eax,(%esp)
c010a8fd:	e8 1c da ff ff       	call   c010831e <mm_destroy>
        }
        // 当前进程不再有内存管理结构
        current->mm = NULL;
c010a902:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a907:	c7 40 18 00 00 00 00 	movl   $0x0,0x18(%eax)
    }
    // 加载新的程序代码
    int ret;
    if ((ret = load_icode(binary, size)) != 0) {
c010a90e:	8b 45 14             	mov    0x14(%ebp),%eax
c010a911:	89 44 24 04          	mov    %eax,0x4(%esp)
c010a915:	8b 45 10             	mov    0x10(%ebp),%eax
c010a918:	89 04 24             	mov    %eax,(%esp)
c010a91b:	e8 c0 f8 ff ff       	call   c010a1e0 <load_icode>
c010a920:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010a923:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010a927:	75 1b                	jne    c010a944 <do_execve+0x108>
        // 如果加载失败，终止当前进程
        goto execve_exit;
    }
    // 设置当前进程的名称为新的程序名称
    set_proc_name(current, local_name);
c010a929:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a92e:	8d 55 dc             	lea    -0x24(%ebp),%edx
c010a931:	89 54 24 04          	mov    %edx,0x4(%esp)
c010a935:	89 04 24             	mov    %eax,(%esp)
c010a938:	e8 84 ed ff ff       	call   c01096c1 <set_proc_name>
    return 0;
c010a93d:	b8 00 00 00 00       	mov    $0x0,%eax
c010a942:	eb 2f                	jmp    c010a973 <do_execve+0x137>
        goto execve_exit;
c010a944:	90                   	nop

execve_exit:
// 加载失败时的清理工作
    do_exit(ret);
c010a945:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010a948:	89 04 24             	mov    %eax,(%esp)
c010a94b:	e8 c0 f6 ff ff       	call   c010a010 <do_exit>
    panic("already exit: %e.\n", ret);
c010a950:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010a953:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010a957:	c7 44 24 08 93 e2 10 	movl   $0xc010e293,0x8(%esp)
c010a95e:	c0 
c010a95f:	c7 44 24 04 8a 03 00 	movl   $0x38a,0x4(%esp)
c010a966:	00 
c010a967:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010a96e:	e8 c8 63 ff ff       	call   c0100d3b <__panic>
}
c010a973:	89 ec                	mov    %ebp,%esp
c010a975:	5d                   	pop    %ebp
c010a976:	c3                   	ret    

c010a977 <do_yield>:

// do_yield - ask the scheduler to reschedule
int
do_yield(void) {
c010a977:	55                   	push   %ebp
c010a978:	89 e5                	mov    %esp,%ebp
    current->need_resched = 1;
c010a97a:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a97f:	c7 40 10 01 00 00 00 	movl   $0x1,0x10(%eax)
    return 0;
c010a986:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010a98b:	5d                   	pop    %ebp
c010a98c:	c3                   	ret    

c010a98d <do_wait>:
 * 它首先检查参数的有效性，然后寻找指定的子进程如果找到已终止的子进程，
 * 则回收其资源并返回子进程的退出状态码如果没有找到已终止的子进程，则当前进程进入睡眠状态，
 * 直到有子进程终止或者没有子进程可等待时返回错误代码
 */
int
do_wait(int pid, int *code_store) {
c010a98d:	55                   	push   %ebp
c010a98e:	89 e5                	mov    %esp,%ebp
c010a990:	83 ec 28             	sub    $0x28,%esp
    // 获取当前进程的内存描述符
    struct mm_struct *mm = current->mm;
c010a993:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010a998:	8b 40 18             	mov    0x18(%eax),%eax
c010a99b:	89 45 ec             	mov    %eax,-0x14(%ebp)
     // 如果code_store不为NULL，检查其指向的用户内存区域是否有效
    if (code_store != NULL) {
c010a99e:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010a9a2:	74 30                	je     c010a9d4 <do_wait+0x47>
        if (!user_mem_check(mm, (uintptr_t)code_store, sizeof(int), 1)) {
c010a9a4:	8b 45 0c             	mov    0xc(%ebp),%eax
c010a9a7:	c7 44 24 0c 01 00 00 	movl   $0x1,0xc(%esp)
c010a9ae:	00 
c010a9af:	c7 44 24 08 04 00 00 	movl   $0x4,0x8(%esp)
c010a9b6:	00 
c010a9b7:	89 44 24 04          	mov    %eax,0x4(%esp)
c010a9bb:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010a9be:	89 04 24             	mov    %eax,(%esp)
c010a9c1:	e8 94 e6 ff ff       	call   c010905a <user_mem_check>
c010a9c6:	85 c0                	test   %eax,%eax
c010a9c8:	75 0a                	jne    c010a9d4 <do_wait+0x47>
            return -E_INVAL;
c010a9ca:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
c010a9cf:	e9 47 01 00 00       	jmp    c010ab1b <do_wait+0x18e>
        }
    }
    // 定义指向进程结构的指针以及布尔变量用于控制流程
    struct proc_struct *proc;
    bool intr_flag, haskid;
repeat:
c010a9d4:	90                   	nop
// 初始化haskid为0，表示尚未找到可等待的子进程
    haskid = 0;
c010a9d5:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)

    // 如果pid不为0，寻找指定的子进程
    if (pid != 0) {
c010a9dc:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c010a9e0:	74 36                	je     c010aa18 <do_wait+0x8b>
        proc = find_proc(pid);
c010a9e2:	8b 45 08             	mov    0x8(%ebp),%eax
c010a9e5:	89 04 24             	mov    %eax,(%esp)
c010a9e8:	e8 d2 f0 ff ff       	call   c0109abf <find_proc>
c010a9ed:	89 45 f4             	mov    %eax,-0xc(%ebp)
        if (proc != NULL && proc->parent == current) {
c010a9f0:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010a9f4:	74 4f                	je     c010aa45 <do_wait+0xb8>
c010a9f6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010a9f9:	8b 50 14             	mov    0x14(%eax),%edx
c010a9fc:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010aa01:	39 c2                	cmp    %eax,%edx
c010aa03:	75 40                	jne    c010aa45 <do_wait+0xb8>
            haskid = 1;
c010aa05:	c7 45 f0 01 00 00 00 	movl   $0x1,-0x10(%ebp)
            if (proc->state == PROC_ZOMBIE) {
c010aa0c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010aa0f:	8b 00                	mov    (%eax),%eax
c010aa11:	83 f8 03             	cmp    $0x3,%eax
c010aa14:	75 2f                	jne    c010aa45 <do_wait+0xb8>
                goto found;
c010aa16:	eb 7e                	jmp    c010aa96 <do_wait+0x109>
            }
        }
    }
    // 如果pid为0，遍历所有子进程寻找已终止的子进程
    else {
        proc = current->cptr;
c010aa18:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010aa1d:	8b 40 70             	mov    0x70(%eax),%eax
c010aa20:	89 45 f4             	mov    %eax,-0xc(%ebp)
        for (; proc != NULL; proc = proc->optr) {
c010aa23:	eb 1a                	jmp    c010aa3f <do_wait+0xb2>
            haskid = 1;
c010aa25:	c7 45 f0 01 00 00 00 	movl   $0x1,-0x10(%ebp)
            if (proc->state == PROC_ZOMBIE) {
c010aa2c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010aa2f:	8b 00                	mov    (%eax),%eax
c010aa31:	83 f8 03             	cmp    $0x3,%eax
c010aa34:	74 5f                	je     c010aa95 <do_wait+0x108>
        for (; proc != NULL; proc = proc->optr) {
c010aa36:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010aa39:	8b 40 78             	mov    0x78(%eax),%eax
c010aa3c:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010aa3f:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010aa43:	75 e0                	jne    c010aa25 <do_wait+0x98>
                goto found;
            }
        }
    }
    // 如果有子进程但都不是已终止状态，当前进程进入睡眠状态等待
    if (haskid) {
c010aa45:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010aa49:	74 40                	je     c010aa8b <do_wait+0xfe>
        current->state = PROC_SLEEPING;
c010aa4b:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010aa50:	c7 00 01 00 00 00    	movl   $0x1,(%eax)
        current->wait_state = WT_CHILD;
c010aa56:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010aa5b:	c7 40 6c 01 00 00 80 	movl   $0x80000001,0x6c(%eax)
        schedule();
c010aa62:	e8 15 06 00 00       	call   c010b07c <schedule>
        if (current->flags & PF_EXITING) {
c010aa67:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010aa6c:	8b 40 44             	mov    0x44(%eax),%eax
c010aa6f:	83 e0 01             	and    $0x1,%eax
c010aa72:	85 c0                	test   %eax,%eax
c010aa74:	0f 84 5b ff ff ff    	je     c010a9d5 <do_wait+0x48>
            do_exit(-E_KILLED);
c010aa7a:	c7 04 24 f7 ff ff ff 	movl   $0xfffffff7,(%esp)
c010aa81:	e8 8a f5 ff ff       	call   c010a010 <do_exit>
        }
        goto repeat;
c010aa86:	e9 4a ff ff ff       	jmp    c010a9d5 <do_wait+0x48>
    }
    // 如果没有子进程可等待，返回错误代码
    return -E_BAD_PROC;
c010aa8b:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
c010aa90:	e9 86 00 00 00       	jmp    c010ab1b <do_wait+0x18e>
                goto found;
c010aa95:	90                   	nop

found:
// 确保找到的进程不是idleproc或initproc，因为它们不应该被等待
    if (proc == idleproc || proc == initproc) {
c010aa96:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010aa9b:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010aa9e:	74 0a                	je     c010aaaa <do_wait+0x11d>
c010aaa0:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010aaa5:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010aaa8:	75 1c                	jne    c010aac6 <do_wait+0x139>
        panic("wait idleproc or initproc.\n");
c010aaaa:	c7 44 24 08 a6 e2 10 	movl   $0xc010e2a6,0x8(%esp)
c010aab1:	c0 
c010aab2:	c7 44 24 04 d8 03 00 	movl   $0x3d8,0x4(%esp)
c010aab9:	00 
c010aaba:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010aac1:	e8 75 62 ff ff       	call   c0100d3b <__panic>
    }
    // 如果需要，存储子进程的退出状态码到code_store指向的内存位置
    if (code_store != NULL) {
c010aac6:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010aaca:	74 0b                	je     c010aad7 <do_wait+0x14a>
        *code_store = proc->exit_code;
c010aacc:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010aacf:	8b 50 68             	mov    0x68(%eax),%edx
c010aad2:	8b 45 0c             	mov    0xc(%ebp),%eax
c010aad5:	89 10                	mov    %edx,(%eax)
    }
    // 保存中断标志并临时禁用中断，以确保操作的原子性
    local_intr_save(intr_flag);
c010aad7:	e8 a4 e8 ff ff       	call   c0109380 <__intr_save>
c010aadc:	89 45 e8             	mov    %eax,-0x18(%ebp)
    {
         // 从进程哈希表中移除进程，并移除其与其他进程的链接
        unhash_proc(proc);
c010aadf:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010aae2:	89 04 24             	mov    %eax,(%esp)
c010aae5:	e8 9d ef ff ff       	call   c0109a87 <unhash_proc>
        remove_links(proc);
c010aaea:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010aaed:	89 04 24             	mov    %eax,(%esp)
c010aaf0:	e8 fe ec ff ff       	call   c01097f3 <remove_links>
    }
    // 恢复中断状态
    local_intr_restore(intr_flag);
c010aaf5:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010aaf8:	89 04 24             	mov    %eax,(%esp)
c010aafb:	e8 ac e8 ff ff       	call   c01093ac <__intr_restore>
    // 释放进程的内核栈和内存资源
    put_kstack(proc);
c010ab00:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010ab03:	89 04 24             	mov    %eax,(%esp)
c010ab06:	e8 dc f0 ff ff       	call   c0109be7 <put_kstack>
    kfree(proc);
c010ab0b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010ab0e:	89 04 24             	mov    %eax,(%esp)
c010ab11:	e8 f7 a1 ff ff       	call   c0104d0d <kfree>
    // 成功完成等待操作，返回0
    return 0;
c010ab16:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010ab1b:	89 ec                	mov    %ebp,%esp
c010ab1d:	5d                   	pop    %ebp
c010ab1e:	c3                   	ret    

c010ab1f <do_kill>:

// do_kill - kill process with pid by set this process's flags with PF_EXITING
int
do_kill(int pid) {
c010ab1f:	55                   	push   %ebp
c010ab20:	89 e5                	mov    %esp,%ebp
c010ab22:	83 ec 28             	sub    $0x28,%esp
    struct proc_struct *proc;
    if ((proc = find_proc(pid)) != NULL) {
c010ab25:	8b 45 08             	mov    0x8(%ebp),%eax
c010ab28:	89 04 24             	mov    %eax,(%esp)
c010ab2b:	e8 8f ef ff ff       	call   c0109abf <find_proc>
c010ab30:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010ab33:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010ab37:	74 41                	je     c010ab7a <do_kill+0x5b>
        if (!(proc->flags & PF_EXITING)) {
c010ab39:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010ab3c:	8b 40 44             	mov    0x44(%eax),%eax
c010ab3f:	83 e0 01             	and    $0x1,%eax
c010ab42:	85 c0                	test   %eax,%eax
c010ab44:	75 2d                	jne    c010ab73 <do_kill+0x54>
            proc->flags |= PF_EXITING;
c010ab46:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010ab49:	8b 40 44             	mov    0x44(%eax),%eax
c010ab4c:	83 c8 01             	or     $0x1,%eax
c010ab4f:	89 c2                	mov    %eax,%edx
c010ab51:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010ab54:	89 50 44             	mov    %edx,0x44(%eax)
            if (proc->wait_state & WT_INTERRUPTED) {
c010ab57:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010ab5a:	8b 40 6c             	mov    0x6c(%eax),%eax
c010ab5d:	85 c0                	test   %eax,%eax
c010ab5f:	79 0b                	jns    c010ab6c <do_kill+0x4d>
                wakeup_proc(proc);
c010ab61:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010ab64:	89 04 24             	mov    %eax,(%esp)
c010ab67:	e8 89 04 00 00       	call   c010aff5 <wakeup_proc>
            }
            return 0;
c010ab6c:	b8 00 00 00 00       	mov    $0x0,%eax
c010ab71:	eb 0c                	jmp    c010ab7f <do_kill+0x60>
        }
        return -E_KILLED;
c010ab73:	b8 f7 ff ff ff       	mov    $0xfffffff7,%eax
c010ab78:	eb 05                	jmp    c010ab7f <do_kill+0x60>
    }
    return -E_INVAL;
c010ab7a:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
}
c010ab7f:	89 ec                	mov    %ebp,%esp
c010ab81:	5d                   	pop    %ebp
c010ab82:	c3                   	ret    

c010ab83 <kernel_execve>:
 * @return 返回系统调用的结果如果成功，通常返回0；如果失败，返回错误码
 * 
 * 注意：该函数使用内联汇编来触发系统调用，这是一种低级操作，需要对系统调用和汇编语言有深入的了解
 */
static int
kernel_execve(const char *name, unsigned char *binary, size_t size) {
c010ab83:	55                   	push   %ebp
c010ab84:	89 e5                	mov    %esp,%ebp
c010ab86:	57                   	push   %edi
c010ab87:	56                   	push   %esi
c010ab88:	53                   	push   %ebx
c010ab89:	83 ec 2c             	sub    $0x2c,%esp
    int ret, len = strlen(name);
c010ab8c:	8b 45 08             	mov    0x8(%ebp),%eax
c010ab8f:	89 04 24             	mov    %eax,(%esp)
c010ab92:	e8 30 0f 00 00       	call   c010bac7 <strlen>
c010ab97:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    asm volatile (
c010ab9a:	b8 04 00 00 00       	mov    $0x4,%eax
c010ab9f:	8b 55 08             	mov    0x8(%ebp),%edx
c010aba2:	8b 4d e4             	mov    -0x1c(%ebp),%ecx
c010aba5:	8b 5d 0c             	mov    0xc(%ebp),%ebx
c010aba8:	8b 75 10             	mov    0x10(%ebp),%esi
c010abab:	89 f7                	mov    %esi,%edi
c010abad:	cd 80                	int    $0x80
c010abaf:	89 45 e0             	mov    %eax,-0x20(%ebp)
        "int %1;"
        : "=a" (ret)
        : "i" (T_SYSCALL), "0" (SYS_exec), "d" (name), "c" (len), "b" (binary), "D" (size)
        : "memory");
    return ret;
c010abb2:	8b 45 e0             	mov    -0x20(%ebp),%eax
}
c010abb5:	83 c4 2c             	add    $0x2c,%esp
c010abb8:	5b                   	pop    %ebx
c010abb9:	5e                   	pop    %esi
c010abba:	5f                   	pop    %edi
c010abbb:	5d                   	pop    %ebp
c010abbc:	c3                   	ret    

c010abbd <user_main>:

#define KERNEL_EXECVE2(x, xstart, xsize)        __KERNEL_EXECVE2(x, xstart, xsize)

// user_main - kernel thread used to exec a user program
static int
user_main(void *arg) {
c010abbd:	55                   	push   %ebp
c010abbe:	89 e5                	mov    %esp,%ebp
c010abc0:	83 ec 18             	sub    $0x18,%esp
#ifdef TEST
    KERNEL_EXECVE2(TEST, TESTSTART, TESTSIZE);
#else
    KERNEL_EXECVE(hello);
c010abc3:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010abc8:	8b 40 04             	mov    0x4(%eax),%eax
c010abcb:	c7 44 24 08 c2 e2 10 	movl   $0xc010e2c2,0x8(%esp)
c010abd2:	c0 
c010abd3:	89 44 24 04          	mov    %eax,0x4(%esp)
c010abd7:	c7 04 24 c8 e2 10 c0 	movl   $0xc010e2c8,(%esp)
c010abde:	e8 95 57 ff ff       	call   c0100378 <cprintf>
c010abe3:	b8 f4 77 00 00       	mov    $0x77f4,%eax
c010abe8:	89 44 24 08          	mov    %eax,0x8(%esp)
c010abec:	c7 44 24 04 9c bb 16 	movl   $0xc016bb9c,0x4(%esp)
c010abf3:	c0 
c010abf4:	c7 04 24 c2 e2 10 c0 	movl   $0xc010e2c2,(%esp)
c010abfb:	e8 83 ff ff ff       	call   c010ab83 <kernel_execve>
#endif
    panic("user_main execve failed.\n");
c010ac00:	c7 44 24 08 ef e2 10 	movl   $0xc010e2ef,0x8(%esp)
c010ac07:	c0 
c010ac08:	c7 44 24 04 35 04 00 	movl   $0x435,0x4(%esp)
c010ac0f:	00 
c010ac10:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010ac17:	e8 1f 61 ff ff       	call   c0100d3b <__panic>

c010ac1c <init_main>:
 * 
 * @param arg 传递给函数的参数，在此函数中未使用
 * @return 返回0表示成功执行
 */
static int
init_main(void *arg) {
c010ac1c:	55                   	push   %ebp
c010ac1d:	89 e5                	mov    %esp,%ebp
c010ac1f:	83 ec 38             	sub    $0x38,%esp
    // 保存当前空闲页面数量和内核已分配内存大小，用于后续检查
    size_t nr_free_pages_store = nr_free_pages();
c010ac22:	e8 fc a5 ff ff       	call   c0105223 <nr_free_pages>
c010ac27:	89 45 f4             	mov    %eax,-0xc(%ebp)
    size_t kernel_allocated_store = kallocated();
c010ac2a:	e8 9e 9f ff ff       	call   c0104bcd <kallocated>
c010ac2f:	89 45 f0             	mov    %eax,-0x10(%ebp)

    // 创建内核线程来执行用户主函数，如果创建失败，则系统陷入恐慌
    int pid = kernel_thread(user_main, NULL, 0);
c010ac32:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c010ac39:	00 
c010ac3a:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010ac41:	00 
c010ac42:	c7 04 24 bd ab 10 c0 	movl   $0xc010abbd,(%esp)
c010ac49:	e8 e5 ee ff ff       	call   c0109b33 <kernel_thread>
c010ac4e:	89 45 ec             	mov    %eax,-0x14(%ebp)
    if (pid <= 0) {
c010ac51:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c010ac55:	7f 21                	jg     c010ac78 <init_main+0x5c>
        panic("create user_main failed.\n");
c010ac57:	c7 44 24 08 09 e3 10 	movl   $0xc010e309,0x8(%esp)
c010ac5e:	c0 
c010ac5f:	c7 44 24 04 55 04 00 	movl   $0x455,0x4(%esp)
c010ac66:	00 
c010ac67:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010ac6e:	e8 c8 60 ff ff       	call   c0100d3b <__panic>
    }

    // 循环等待和调度，直到所有用户模式进程结束
    while (do_wait(0, NULL) == 0) {
        schedule();
c010ac73:	e8 04 04 00 00       	call   c010b07c <schedule>
    while (do_wait(0, NULL) == 0) {
c010ac78:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010ac7f:	00 
c010ac80:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c010ac87:	e8 01 fd ff ff       	call   c010a98d <do_wait>
c010ac8c:	85 c0                	test   %eax,%eax
c010ac8e:	74 e3                	je     c010ac73 <init_main+0x57>
    }

    // 所有用户模式进程结束后，打印消息
    cprintf("all user-mode processes have quit.\n");
c010ac90:	c7 04 24 24 e3 10 c0 	movl   $0xc010e324,(%esp)
c010ac97:	e8 dc 56 ff ff       	call   c0100378 <cprintf>

    // 断言系统状态符合预期
    assert(initproc->cptr == NULL && initproc->yptr == NULL && initproc->optr == NULL);
c010ac9c:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010aca1:	8b 40 70             	mov    0x70(%eax),%eax
c010aca4:	85 c0                	test   %eax,%eax
c010aca6:	75 18                	jne    c010acc0 <init_main+0xa4>
c010aca8:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010acad:	8b 40 74             	mov    0x74(%eax),%eax
c010acb0:	85 c0                	test   %eax,%eax
c010acb2:	75 0c                	jne    c010acc0 <init_main+0xa4>
c010acb4:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010acb9:	8b 40 78             	mov    0x78(%eax),%eax
c010acbc:	85 c0                	test   %eax,%eax
c010acbe:	74 24                	je     c010ace4 <init_main+0xc8>
c010acc0:	c7 44 24 0c 48 e3 10 	movl   $0xc010e348,0xc(%esp)
c010acc7:	c0 
c010acc8:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010accf:	c0 
c010acd0:	c7 44 24 04 61 04 00 	movl   $0x461,0x4(%esp)
c010acd7:	00 
c010acd8:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010acdf:	e8 57 60 ff ff       	call   c0100d3b <__panic>
    assert(nr_process == 2);
c010ace4:	a1 40 61 1a c0       	mov    0xc01a6140,%eax
c010ace9:	83 f8 02             	cmp    $0x2,%eax
c010acec:	74 24                	je     c010ad12 <init_main+0xf6>
c010acee:	c7 44 24 0c 93 e3 10 	movl   $0xc010e393,0xc(%esp)
c010acf5:	c0 
c010acf6:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010acfd:	c0 
c010acfe:	c7 44 24 04 62 04 00 	movl   $0x462,0x4(%esp)
c010ad05:	00 
c010ad06:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010ad0d:	e8 29 60 ff ff       	call   c0100d3b <__panic>
c010ad12:	c7 45 e8 20 41 1a c0 	movl   $0xc01a4120,-0x18(%ebp)
c010ad19:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010ad1c:	8b 40 04             	mov    0x4(%eax),%eax
    assert(list_next(&proc_list) == &(initproc->list_link));
c010ad1f:	8b 15 2c 41 1a c0    	mov    0xc01a412c,%edx
c010ad25:	83 c2 58             	add    $0x58,%edx
c010ad28:	39 d0                	cmp    %edx,%eax
c010ad2a:	74 24                	je     c010ad50 <init_main+0x134>
c010ad2c:	c7 44 24 0c a4 e3 10 	movl   $0xc010e3a4,0xc(%esp)
c010ad33:	c0 
c010ad34:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010ad3b:	c0 
c010ad3c:	c7 44 24 04 63 04 00 	movl   $0x463,0x4(%esp)
c010ad43:	00 
c010ad44:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010ad4b:	e8 eb 5f ff ff       	call   c0100d3b <__panic>
c010ad50:	c7 45 e4 20 41 1a c0 	movl   $0xc01a4120,-0x1c(%ebp)
    return listelm->prev;
c010ad57:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010ad5a:	8b 00                	mov    (%eax),%eax
    assert(list_prev(&proc_list) == &(initproc->list_link));
c010ad5c:	8b 15 2c 41 1a c0    	mov    0xc01a412c,%edx
c010ad62:	83 c2 58             	add    $0x58,%edx
c010ad65:	39 d0                	cmp    %edx,%eax
c010ad67:	74 24                	je     c010ad8d <init_main+0x171>
c010ad69:	c7 44 24 0c d4 e3 10 	movl   $0xc010e3d4,0xc(%esp)
c010ad70:	c0 
c010ad71:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010ad78:	c0 
c010ad79:	c7 44 24 04 64 04 00 	movl   $0x464,0x4(%esp)
c010ad80:	00 
c010ad81:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010ad88:	e8 ae 5f ff ff       	call   c0100d3b <__panic>

    // 如果所有检查通过，打印内存检查通过的消息
    cprintf("init check memory pass.\n");
c010ad8d:	c7 04 24 04 e4 10 c0 	movl   $0xc010e404,(%esp)
c010ad94:	e8 df 55 ff ff       	call   c0100378 <cprintf>
    return 0;
c010ad99:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010ad9e:	89 ec                	mov    %ebp,%esp
c010ada0:	5d                   	pop    %ebp
c010ada1:	c3                   	ret    

c010ada2 <proc_init>:

// proc_init - set up the first kernel thread idleproc "idle" by itself and 
//           - create the second kernel thread init_main
void
proc_init(void) {
c010ada2:	55                   	push   %ebp
c010ada3:	89 e5                	mov    %esp,%ebp
c010ada5:	83 ec 28             	sub    $0x28,%esp
c010ada8:	c7 45 ec 20 41 1a c0 	movl   $0xc01a4120,-0x14(%ebp)
    elm->prev = elm->next = elm;
c010adaf:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010adb2:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010adb5:	89 50 04             	mov    %edx,0x4(%eax)
c010adb8:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010adbb:	8b 50 04             	mov    0x4(%eax),%edx
c010adbe:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010adc1:	89 10                	mov    %edx,(%eax)
}
c010adc3:	90                   	nop

    // 初始化全局进程列表
    list_init(&proc_list);

    // 初始化哈希列表，用于快速查找进程
    for (i = 0; i < HASH_LIST_SIZE; i ++) {
c010adc4:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c010adcb:	eb 26                	jmp    c010adf3 <proc_init+0x51>
        list_init(hash_list + i);
c010adcd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010add0:	c1 e0 03             	shl    $0x3,%eax
c010add3:	05 40 41 1a c0       	add    $0xc01a4140,%eax
c010add8:	89 45 e8             	mov    %eax,-0x18(%ebp)
    elm->prev = elm->next = elm;
c010addb:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010adde:	8b 55 e8             	mov    -0x18(%ebp),%edx
c010ade1:	89 50 04             	mov    %edx,0x4(%eax)
c010ade4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010ade7:	8b 50 04             	mov    0x4(%eax),%edx
c010adea:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010aded:	89 10                	mov    %edx,(%eax)
}
c010adef:	90                   	nop
    for (i = 0; i < HASH_LIST_SIZE; i ++) {
c010adf0:	ff 45 f4             	incl   -0xc(%ebp)
c010adf3:	81 7d f4 ff 03 00 00 	cmpl   $0x3ff,-0xc(%ebp)
c010adfa:	7e d1                	jle    c010adcd <proc_init+0x2b>
    }

    // 分配空闲进程idleproc，这是系统中的第一个进程
    if ((idleproc = alloc_proc()) == NULL) {
c010adfc:	e8 cd e7 ff ff       	call   c01095ce <alloc_proc>
c010ae01:	a3 28 41 1a c0       	mov    %eax,0xc01a4128
c010ae06:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010ae0b:	85 c0                	test   %eax,%eax
c010ae0d:	75 1c                	jne    c010ae2b <proc_init+0x89>
        panic("cannot alloc idleproc.\n");
c010ae0f:	c7 44 24 08 1d e4 10 	movl   $0xc010e41d,0x8(%esp)
c010ae16:	c0 
c010ae17:	c7 44 24 04 7b 04 00 	movl   $0x47b,0x4(%esp)
c010ae1e:	00 
c010ae1f:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010ae26:	e8 10 5f ff ff       	call   c0100d3b <__panic>
    }

    // 设置idleproc的基本信息
    idleproc->pid = 0;
c010ae2b:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010ae30:	c7 40 04 00 00 00 00 	movl   $0x0,0x4(%eax)
    idleproc->state = PROC_RUNNABLE;
c010ae37:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010ae3c:	c7 00 02 00 00 00    	movl   $0x2,(%eax)
    idleproc->kstack = (uintptr_t)bootstack;
c010ae42:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010ae47:	ba 00 d0 12 c0       	mov    $0xc012d000,%edx
c010ae4c:	89 50 0c             	mov    %edx,0xc(%eax)
    idleproc->need_resched = 1;
c010ae4f:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010ae54:	c7 40 10 01 00 00 00 	movl   $0x1,0x10(%eax)
    set_proc_name(idleproc, "idle");
c010ae5b:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010ae60:	c7 44 24 04 35 e4 10 	movl   $0xc010e435,0x4(%esp)
c010ae67:	c0 
c010ae68:	89 04 24             	mov    %eax,(%esp)
c010ae6b:	e8 51 e8 ff ff       	call   c01096c1 <set_proc_name>
    nr_process ++;
c010ae70:	a1 40 61 1a c0       	mov    0xc01a6140,%eax
c010ae75:	40                   	inc    %eax
c010ae76:	a3 40 61 1a c0       	mov    %eax,0xc01a6140

    // 将当前进程设置为idleproc
    current = idleproc;
c010ae7b:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010ae80:	a3 30 41 1a c0       	mov    %eax,0xc01a4130

    // 创建初始化进程init_main，这是系统中的第二个进程
    int pid = kernel_thread(init_main, NULL, 0);
c010ae85:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c010ae8c:	00 
c010ae8d:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010ae94:	00 
c010ae95:	c7 04 24 1c ac 10 c0 	movl   $0xc010ac1c,(%esp)
c010ae9c:	e8 92 ec ff ff       	call   c0109b33 <kernel_thread>
c010aea1:	89 45 f0             	mov    %eax,-0x10(%ebp)
    if (pid <= 0) {
c010aea4:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010aea8:	7f 1c                	jg     c010aec6 <proc_init+0x124>
        panic("create init_main failed.\n");
c010aeaa:	c7 44 24 08 3a e4 10 	movl   $0xc010e43a,0x8(%esp)
c010aeb1:	c0 
c010aeb2:	c7 44 24 04 8c 04 00 	movl   $0x48c,0x4(%esp)
c010aeb9:	00 
c010aeba:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010aec1:	e8 75 5e ff ff       	call   c0100d3b <__panic>
    }

    // 查找并设置初始化进程initproc
    initproc = find_proc(pid);
c010aec6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010aec9:	89 04 24             	mov    %eax,(%esp)
c010aecc:	e8 ee eb ff ff       	call   c0109abf <find_proc>
c010aed1:	a3 2c 41 1a c0       	mov    %eax,0xc01a412c
    set_proc_name(initproc, "init");
c010aed6:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010aedb:	c7 44 24 04 54 e4 10 	movl   $0xc010e454,0x4(%esp)
c010aee2:	c0 
c010aee3:	89 04 24             	mov    %eax,(%esp)
c010aee6:	e8 d6 e7 ff ff       	call   c01096c1 <set_proc_name>

    // 断言确保idleproc和initproc正确初始化
    assert(idleproc != NULL && idleproc->pid == 0);
c010aeeb:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010aef0:	85 c0                	test   %eax,%eax
c010aef2:	74 0c                	je     c010af00 <proc_init+0x15e>
c010aef4:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010aef9:	8b 40 04             	mov    0x4(%eax),%eax
c010aefc:	85 c0                	test   %eax,%eax
c010aefe:	74 24                	je     c010af24 <proc_init+0x182>
c010af00:	c7 44 24 0c 5c e4 10 	movl   $0xc010e45c,0xc(%esp)
c010af07:	c0 
c010af08:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010af0f:	c0 
c010af10:	c7 44 24 04 94 04 00 	movl   $0x494,0x4(%esp)
c010af17:	00 
c010af18:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010af1f:	e8 17 5e ff ff       	call   c0100d3b <__panic>
    assert(initproc != NULL && initproc->pid == 1);
c010af24:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010af29:	85 c0                	test   %eax,%eax
c010af2b:	74 0d                	je     c010af3a <proc_init+0x198>
c010af2d:	a1 2c 41 1a c0       	mov    0xc01a412c,%eax
c010af32:	8b 40 04             	mov    0x4(%eax),%eax
c010af35:	83 f8 01             	cmp    $0x1,%eax
c010af38:	74 24                	je     c010af5e <proc_init+0x1bc>
c010af3a:	c7 44 24 0c 84 e4 10 	movl   $0xc010e484,0xc(%esp)
c010af41:	c0 
c010af42:	c7 44 24 08 c9 e0 10 	movl   $0xc010e0c9,0x8(%esp)
c010af49:	c0 
c010af4a:	c7 44 24 04 95 04 00 	movl   $0x495,0x4(%esp)
c010af51:	00 
c010af52:	c7 04 24 9c e0 10 c0 	movl   $0xc010e09c,(%esp)
c010af59:	e8 dd 5d ff ff       	call   c0100d3b <__panic>
}
c010af5e:	90                   	nop
c010af5f:	89 ec                	mov    %ebp,%esp
c010af61:	5d                   	pop    %ebp
c010af62:	c3                   	ret    

c010af63 <cpu_idle>:

// cpu_idle - at the end of kern_init, the first kernel thread idleproc will do below works
void
cpu_idle(void) {
c010af63:	55                   	push   %ebp
c010af64:	89 e5                	mov    %esp,%ebp
c010af66:	83 ec 08             	sub    $0x8,%esp
    while (1) {
        //检查当前进程是否需要重新调度
        if (current->need_resched) {
c010af69:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010af6e:	8b 40 10             	mov    0x10(%eax),%eax
c010af71:	85 c0                	test   %eax,%eax
c010af73:	74 f4                	je     c010af69 <cpu_idle+0x6>
            schedule();
c010af75:	e8 02 01 00 00       	call   c010b07c <schedule>
        if (current->need_resched) {
c010af7a:	eb ed                	jmp    c010af69 <cpu_idle+0x6>

c010af7c <switch_to>:
.text
.globl switch_to
switch_to:                      # switch_to(from, to)

    # save from's registers
    movl 4(%esp), %eax          # eax points to from
c010af7c:	8b 44 24 04          	mov    0x4(%esp),%eax
    popl 0(%eax)                # save eip !popl
c010af80:	8f 00                	pop    (%eax)
    movl %esp, 4(%eax)
c010af82:	89 60 04             	mov    %esp,0x4(%eax)
    movl %ebx, 8(%eax)
c010af85:	89 58 08             	mov    %ebx,0x8(%eax)
    movl %ecx, 12(%eax)
c010af88:	89 48 0c             	mov    %ecx,0xc(%eax)
    movl %edx, 16(%eax)
c010af8b:	89 50 10             	mov    %edx,0x10(%eax)
    movl %esi, 20(%eax)
c010af8e:	89 70 14             	mov    %esi,0x14(%eax)
    movl %edi, 24(%eax)
c010af91:	89 78 18             	mov    %edi,0x18(%eax)
    movl %ebp, 28(%eax)
c010af94:	89 68 1c             	mov    %ebp,0x1c(%eax)

    # restore to's registers
    movl 4(%esp), %eax          # not 8(%esp): popped return address already
c010af97:	8b 44 24 04          	mov    0x4(%esp),%eax
                                # eax now points to to
    movl 28(%eax), %ebp
c010af9b:	8b 68 1c             	mov    0x1c(%eax),%ebp
    movl 24(%eax), %edi
c010af9e:	8b 78 18             	mov    0x18(%eax),%edi
    movl 20(%eax), %esi
c010afa1:	8b 70 14             	mov    0x14(%eax),%esi
    movl 16(%eax), %edx
c010afa4:	8b 50 10             	mov    0x10(%eax),%edx
    movl 12(%eax), %ecx
c010afa7:	8b 48 0c             	mov    0xc(%eax),%ecx
    movl 8(%eax), %ebx
c010afaa:	8b 58 08             	mov    0x8(%eax),%ebx
    movl 4(%eax), %esp
c010afad:	8b 60 04             	mov    0x4(%eax),%esp

    pushl 0(%eax)               # push eip
c010afb0:	ff 30                	push   (%eax)

    ret
c010afb2:	c3                   	ret    

c010afb3 <__intr_save>:
__intr_save(void) {
c010afb3:	55                   	push   %ebp
c010afb4:	89 e5                	mov    %esp,%ebp
c010afb6:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c010afb9:	9c                   	pushf  
c010afba:	58                   	pop    %eax
c010afbb:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c010afbe:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c010afc1:	25 00 02 00 00       	and    $0x200,%eax
c010afc6:	85 c0                	test   %eax,%eax
c010afc8:	74 0c                	je     c010afd6 <__intr_save+0x23>
        intr_disable();
c010afca:	e8 22 70 ff ff       	call   c0101ff1 <intr_disable>
        return 1;
c010afcf:	b8 01 00 00 00       	mov    $0x1,%eax
c010afd4:	eb 05                	jmp    c010afdb <__intr_save+0x28>
    return 0;
c010afd6:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010afdb:	89 ec                	mov    %ebp,%esp
c010afdd:	5d                   	pop    %ebp
c010afde:	c3                   	ret    

c010afdf <__intr_restore>:
__intr_restore(bool flag) {
c010afdf:	55                   	push   %ebp
c010afe0:	89 e5                	mov    %esp,%ebp
c010afe2:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c010afe5:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c010afe9:	74 05                	je     c010aff0 <__intr_restore+0x11>
        intr_enable();
c010afeb:	e8 f9 6f ff ff       	call   c0101fe9 <intr_enable>
}
c010aff0:	90                   	nop
c010aff1:	89 ec                	mov    %ebp,%esp
c010aff3:	5d                   	pop    %ebp
c010aff4:	c3                   	ret    

c010aff5 <wakeup_proc>:
#include <proc.h>
#include <sched.h>
#include <assert.h>

void
wakeup_proc(struct proc_struct *proc) {
c010aff5:	55                   	push   %ebp
c010aff6:	89 e5                	mov    %esp,%ebp
c010aff8:	83 ec 28             	sub    $0x28,%esp
    assert(proc->state != PROC_ZOMBIE);
c010affb:	8b 45 08             	mov    0x8(%ebp),%eax
c010affe:	8b 00                	mov    (%eax),%eax
c010b000:	83 f8 03             	cmp    $0x3,%eax
c010b003:	75 24                	jne    c010b029 <wakeup_proc+0x34>
c010b005:	c7 44 24 0c ab e4 10 	movl   $0xc010e4ab,0xc(%esp)
c010b00c:	c0 
c010b00d:	c7 44 24 08 c6 e4 10 	movl   $0xc010e4c6,0x8(%esp)
c010b014:	c0 
c010b015:	c7 44 24 04 09 00 00 	movl   $0x9,0x4(%esp)
c010b01c:	00 
c010b01d:	c7 04 24 db e4 10 c0 	movl   $0xc010e4db,(%esp)
c010b024:	e8 12 5d ff ff       	call   c0100d3b <__panic>
    bool intr_flag;
    local_intr_save(intr_flag);
c010b029:	e8 85 ff ff ff       	call   c010afb3 <__intr_save>
c010b02e:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        if (proc->state != PROC_RUNNABLE) {
c010b031:	8b 45 08             	mov    0x8(%ebp),%eax
c010b034:	8b 00                	mov    (%eax),%eax
c010b036:	83 f8 02             	cmp    $0x2,%eax
c010b039:	74 15                	je     c010b050 <wakeup_proc+0x5b>
            proc->state = PROC_RUNNABLE;
c010b03b:	8b 45 08             	mov    0x8(%ebp),%eax
c010b03e:	c7 00 02 00 00 00    	movl   $0x2,(%eax)
            proc->wait_state = 0;
c010b044:	8b 45 08             	mov    0x8(%ebp),%eax
c010b047:	c7 40 6c 00 00 00 00 	movl   $0x0,0x6c(%eax)
c010b04e:	eb 1c                	jmp    c010b06c <wakeup_proc+0x77>
        }
        else {
            warn("wakeup runnable process.\n");
c010b050:	c7 44 24 08 f1 e4 10 	movl   $0xc010e4f1,0x8(%esp)
c010b057:	c0 
c010b058:	c7 44 24 04 12 00 00 	movl   $0x12,0x4(%esp)
c010b05f:	00 
c010b060:	c7 04 24 db e4 10 c0 	movl   $0xc010e4db,(%esp)
c010b067:	e8 4d 5d ff ff       	call   c0100db9 <__warn>
        }
    }
    local_intr_restore(intr_flag);
c010b06c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b06f:	89 04 24             	mov    %eax,(%esp)
c010b072:	e8 68 ff ff ff       	call   c010afdf <__intr_restore>
}
c010b077:	90                   	nop
c010b078:	89 ec                	mov    %ebp,%esp
c010b07a:	5d                   	pop    %ebp
c010b07b:	c3                   	ret    

c010b07c <schedule>:
 * 如果找到可运行的进程，则选择该进程作为下一个要执行的进程，并进行上下文切换。
 * 如果没有找到可运行的进程，则选择空闲进程作为下一个要执行的进程。
 * 最后，恢复中断状态并退出调度函数。
 */
void
schedule(void) {
c010b07c:	55                   	push   %ebp
c010b07d:	89 e5                	mov    %esp,%ebp
c010b07f:	83 ec 38             	sub    $0x38,%esp
    // 保存中断状态标志
    bool intr_flag;
    // 定义指向进程列表项的指针
    list_entry_t *le, *last;
    // 定义下一个要执行的进程指针，并初始化为NULL
    struct proc_struct *next = NULL;
c010b082:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    // 保存当前中断状态，并禁止中断
    local_intr_save(intr_flag);
c010b089:	e8 25 ff ff ff       	call   c010afb3 <__intr_save>
c010b08e:	89 45 ec             	mov    %eax,-0x14(%ebp)
    {
        // 标记当前进程不需要重新调度
        current->need_resched = 0;
c010b091:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010b096:	c7 40 10 00 00 00 00 	movl   $0x0,0x10(%eax)
         // 确定进程列表的最后一个元素
        last = (current == idleproc) ? &proc_list : &(current->list_link);
c010b09d:	8b 15 30 41 1a c0    	mov    0xc01a4130,%edx
c010b0a3:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010b0a8:	39 c2                	cmp    %eax,%edx
c010b0aa:	74 0a                	je     c010b0b6 <schedule+0x3a>
c010b0ac:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010b0b1:	83 c0 58             	add    $0x58,%eax
c010b0b4:	eb 05                	jmp    c010b0bb <schedule+0x3f>
c010b0b6:	b8 20 41 1a c0       	mov    $0xc01a4120,%eax
c010b0bb:	89 45 e8             	mov    %eax,-0x18(%ebp)
         // 从最后一个元素开始遍历进程列表
        le = last;
c010b0be:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010b0c1:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010b0c4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b0c7:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    return listelm->next;
c010b0ca:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010b0cd:	8b 40 04             	mov    0x4(%eax),%eax
        do {
            // 如果不是进程列表的末尾，则继续查找下一个可运行的进程
            if ((le = list_next(le)) != &proc_list) {
c010b0d0:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010b0d3:	81 7d f4 20 41 1a c0 	cmpl   $0xc01a4120,-0xc(%ebp)
c010b0da:	74 13                	je     c010b0ef <schedule+0x73>
                 // 获取当前列表项对应的进程结构体
                next = le2proc(le, list_link);
c010b0dc:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b0df:	83 e8 58             	sub    $0x58,%eax
c010b0e2:	89 45 f0             	mov    %eax,-0x10(%ebp)
                // 如果进程处于可运行状态，则停止查找
                if (next->state == PROC_RUNNABLE) {
c010b0e5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b0e8:	8b 00                	mov    (%eax),%eax
c010b0ea:	83 f8 02             	cmp    $0x2,%eax
c010b0ed:	74 0a                	je     c010b0f9 <schedule+0x7d>
                    break;
                }
            }
        } while (le != last);
c010b0ef:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b0f2:	3b 45 e8             	cmp    -0x18(%ebp),%eax
c010b0f5:	75 cd                	jne    c010b0c4 <schedule+0x48>
c010b0f7:	eb 01                	jmp    c010b0fa <schedule+0x7e>
                    break;
c010b0f9:	90                   	nop
         // 如果没有找到可运行的进程，则选择空闲进程作为下一个要执行的进程
        if (next == NULL || next->state != PROC_RUNNABLE) {
c010b0fa:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010b0fe:	74 0a                	je     c010b10a <schedule+0x8e>
c010b100:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b103:	8b 00                	mov    (%eax),%eax
c010b105:	83 f8 02             	cmp    $0x2,%eax
c010b108:	74 08                	je     c010b112 <schedule+0x96>
            next = idleproc;
c010b10a:	a1 28 41 1a c0       	mov    0xc01a4128,%eax
c010b10f:	89 45 f0             	mov    %eax,-0x10(%ebp)
        }
         // 增加下一个要执行的进程的运行次数
        next->runs ++;
c010b112:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b115:	8b 40 08             	mov    0x8(%eax),%eax
c010b118:	8d 50 01             	lea    0x1(%eax),%edx
c010b11b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b11e:	89 50 08             	mov    %edx,0x8(%eax)
        // 如果下一个要执行的进程不是当前进程，则进行上下文切换
        if (next != current) {
c010b121:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010b126:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c010b129:	74 0b                	je     c010b136 <schedule+0xba>
            proc_run(next);
c010b12b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b12e:	89 04 24             	mov    %eax,(%esp)
c010b131:	e8 3a e8 ff ff       	call   c0109970 <proc_run>
        }
    }
     // 恢复中断状态
    local_intr_restore(intr_flag);
c010b136:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010b139:	89 04 24             	mov    %eax,(%esp)
c010b13c:	e8 9e fe ff ff       	call   c010afdf <__intr_restore>
}
c010b141:	90                   	nop
c010b142:	89 ec                	mov    %ebp,%esp
c010b144:	5d                   	pop    %ebp
c010b145:	c3                   	ret    

c010b146 <sys_exit>:
#include <stdio.h>
#include <pmm.h>
#include <assert.h>

static int
sys_exit(uint32_t arg[]) {
c010b146:	55                   	push   %ebp
c010b147:	89 e5                	mov    %esp,%ebp
c010b149:	83 ec 28             	sub    $0x28,%esp
    int error_code = (int)arg[0];
c010b14c:	8b 45 08             	mov    0x8(%ebp),%eax
c010b14f:	8b 00                	mov    (%eax),%eax
c010b151:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return do_exit(error_code);
c010b154:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b157:	89 04 24             	mov    %eax,(%esp)
c010b15a:	e8 b1 ee ff ff       	call   c010a010 <do_exit>
}
c010b15f:	89 ec                	mov    %ebp,%esp
c010b161:	5d                   	pop    %ebp
c010b162:	c3                   	ret    

c010b163 <sys_fork>:

//实现进程的创建
static int
sys_fork(uint32_t arg[]) {
c010b163:	55                   	push   %ebp
c010b164:	89 e5                	mov    %esp,%ebp
c010b166:	83 ec 28             	sub    $0x28,%esp
    struct trapframe *tf = current->tf;
c010b169:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010b16e:	8b 40 3c             	mov    0x3c(%eax),%eax
c010b171:	89 45 f4             	mov    %eax,-0xc(%ebp)
    uintptr_t stack = tf->tf_esp;
c010b174:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b177:	8b 40 44             	mov    0x44(%eax),%eax
c010b17a:	89 45 f0             	mov    %eax,-0x10(%ebp)
    return do_fork(0, stack, tf);
c010b17d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b180:	89 44 24 08          	mov    %eax,0x8(%esp)
c010b184:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b187:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b18b:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c010b192:	e8 52 ed ff ff       	call   c0109ee9 <do_fork>
}
c010b197:	89 ec                	mov    %ebp,%esp
c010b199:	5d                   	pop    %ebp
c010b19a:	c3                   	ret    

c010b19b <sys_wait>:

static int
sys_wait(uint32_t arg[]) {
c010b19b:	55                   	push   %ebp
c010b19c:	89 e5                	mov    %esp,%ebp
c010b19e:	83 ec 28             	sub    $0x28,%esp
    int pid = (int)arg[0];
c010b1a1:	8b 45 08             	mov    0x8(%ebp),%eax
c010b1a4:	8b 00                	mov    (%eax),%eax
c010b1a6:	89 45 f4             	mov    %eax,-0xc(%ebp)
    int *store = (int *)arg[1];
c010b1a9:	8b 45 08             	mov    0x8(%ebp),%eax
c010b1ac:	83 c0 04             	add    $0x4,%eax
c010b1af:	8b 00                	mov    (%eax),%eax
c010b1b1:	89 45 f0             	mov    %eax,-0x10(%ebp)
    return do_wait(pid, store);
c010b1b4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b1b7:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b1bb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b1be:	89 04 24             	mov    %eax,(%esp)
c010b1c1:	e8 c7 f7 ff ff       	call   c010a98d <do_wait>
}
c010b1c6:	89 ec                	mov    %ebp,%esp
c010b1c8:	5d                   	pop    %ebp
c010b1c9:	c3                   	ret    

c010b1ca <sys_exec>:

static int
sys_exec(uint32_t arg[]) {
c010b1ca:	55                   	push   %ebp
c010b1cb:	89 e5                	mov    %esp,%ebp
c010b1cd:	83 ec 28             	sub    $0x28,%esp
    const char *name = (const char *)arg[0];
c010b1d0:	8b 45 08             	mov    0x8(%ebp),%eax
c010b1d3:	8b 00                	mov    (%eax),%eax
c010b1d5:	89 45 f4             	mov    %eax,-0xc(%ebp)
    size_t len = (size_t)arg[1];
c010b1d8:	8b 45 08             	mov    0x8(%ebp),%eax
c010b1db:	83 c0 04             	add    $0x4,%eax
c010b1de:	8b 00                	mov    (%eax),%eax
c010b1e0:	89 45 f0             	mov    %eax,-0x10(%ebp)
    unsigned char *binary = (unsigned char *)arg[2];
c010b1e3:	8b 45 08             	mov    0x8(%ebp),%eax
c010b1e6:	83 c0 08             	add    $0x8,%eax
c010b1e9:	8b 00                	mov    (%eax),%eax
c010b1eb:	89 45 ec             	mov    %eax,-0x14(%ebp)
    size_t size = (size_t)arg[3];
c010b1ee:	8b 45 08             	mov    0x8(%ebp),%eax
c010b1f1:	83 c0 0c             	add    $0xc,%eax
c010b1f4:	8b 00                	mov    (%eax),%eax
c010b1f6:	89 45 e8             	mov    %eax,-0x18(%ebp)
    return do_execve(name, len, binary, size);
c010b1f9:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010b1fc:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010b200:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010b203:	89 44 24 08          	mov    %eax,0x8(%esp)
c010b207:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b20a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b20e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b211:	89 04 24             	mov    %eax,(%esp)
c010b214:	e8 23 f6 ff ff       	call   c010a83c <do_execve>
}
c010b219:	89 ec                	mov    %ebp,%esp
c010b21b:	5d                   	pop    %ebp
c010b21c:	c3                   	ret    

c010b21d <sys_yield>:

static int
sys_yield(uint32_t arg[]) {
c010b21d:	55                   	push   %ebp
c010b21e:	89 e5                	mov    %esp,%ebp
c010b220:	83 ec 08             	sub    $0x8,%esp
    return do_yield();
c010b223:	e8 4f f7 ff ff       	call   c010a977 <do_yield>
}
c010b228:	89 ec                	mov    %ebp,%esp
c010b22a:	5d                   	pop    %ebp
c010b22b:	c3                   	ret    

c010b22c <sys_kill>:

static int
sys_kill(uint32_t arg[]) {
c010b22c:	55                   	push   %ebp
c010b22d:	89 e5                	mov    %esp,%ebp
c010b22f:	83 ec 28             	sub    $0x28,%esp
    int pid = (int)arg[0];
c010b232:	8b 45 08             	mov    0x8(%ebp),%eax
c010b235:	8b 00                	mov    (%eax),%eax
c010b237:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return do_kill(pid);
c010b23a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b23d:	89 04 24             	mov    %eax,(%esp)
c010b240:	e8 da f8 ff ff       	call   c010ab1f <do_kill>
}
c010b245:	89 ec                	mov    %ebp,%esp
c010b247:	5d                   	pop    %ebp
c010b248:	c3                   	ret    

c010b249 <sys_getpid>:

//获取当前进程的进程ID（PID）
static int
sys_getpid(uint32_t arg[]) {
c010b249:	55                   	push   %ebp
c010b24a:	89 e5                	mov    %esp,%ebp
    return current->pid;
c010b24c:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010b251:	8b 40 04             	mov    0x4(%eax),%eax
}
c010b254:	5d                   	pop    %ebp
c010b255:	c3                   	ret    

c010b256 <sys_putc>:

static int
sys_putc(uint32_t arg[]) {
c010b256:	55                   	push   %ebp
c010b257:	89 e5                	mov    %esp,%ebp
c010b259:	83 ec 28             	sub    $0x28,%esp
    int c = (int)arg[0];
c010b25c:	8b 45 08             	mov    0x8(%ebp),%eax
c010b25f:	8b 00                	mov    (%eax),%eax
c010b261:	89 45 f4             	mov    %eax,-0xc(%ebp)
    cputchar(c);//将字符 c 输出到控制台
c010b264:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b267:	89 04 24             	mov    %eax,(%esp)
c010b26a:	e8 31 51 ff ff       	call   c01003a0 <cputchar>
    return 0;
c010b26f:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010b274:	89 ec                	mov    %ebp,%esp
c010b276:	5d                   	pop    %ebp
c010b277:	c3                   	ret    

c010b278 <sys_pgdir>:

static int
sys_pgdir(uint32_t arg[]) {
c010b278:	55                   	push   %ebp
c010b279:	89 e5                	mov    %esp,%ebp
c010b27b:	83 ec 08             	sub    $0x8,%esp
    print_pgdir();//打印页目录信息
c010b27e:	e8 7b b9 ff ff       	call   c0106bfe <print_pgdir>
    return 0;
c010b283:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010b288:	89 ec                	mov    %ebp,%esp
c010b28a:	5d                   	pop    %ebp
c010b28b:	c3                   	ret    

c010b28c <syscall>:
};

#define NUM_SYSCALLS        ((sizeof(syscalls)) / (sizeof(syscalls[0])))

void
syscall(void) {
c010b28c:	55                   	push   %ebp
c010b28d:	89 e5                	mov    %esp,%ebp
c010b28f:	83 ec 48             	sub    $0x48,%esp
    //获取当前线程的陷阱帧
    struct trapframe *tf = current->tf;
c010b292:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010b297:	8b 40 3c             	mov    0x3c(%eax),%eax
c010b29a:	89 45 f4             	mov    %eax,-0xc(%ebp)
    uint32_t arg[5];
    //提取系统调用号
    int num = tf->tf_regs.reg_eax;
c010b29d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b2a0:	8b 40 1c             	mov    0x1c(%eax),%eax
c010b2a3:	89 45 f0             	mov    %eax,-0x10(%ebp)
    //检查系统调用号的有效性
    if (num >= 0 && num < NUM_SYSCALLS) {
c010b2a6:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010b2aa:	78 5e                	js     c010b30a <syscall+0x7e>
c010b2ac:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b2af:	83 f8 1f             	cmp    $0x1f,%eax
c010b2b2:	77 56                	ja     c010b30a <syscall+0x7e>
        //调用相应的系统调用处理函数
        if (syscalls[num] != NULL) {
c010b2b4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b2b7:	8b 04 85 a0 fa 12 c0 	mov    -0x3fed0560(,%eax,4),%eax
c010b2be:	85 c0                	test   %eax,%eax
c010b2c0:	74 48                	je     c010b30a <syscall+0x7e>
            arg[0] = tf->tf_regs.reg_edx;
c010b2c2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b2c5:	8b 40 14             	mov    0x14(%eax),%eax
c010b2c8:	89 45 dc             	mov    %eax,-0x24(%ebp)
            arg[1] = tf->tf_regs.reg_ecx;
c010b2cb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b2ce:	8b 40 18             	mov    0x18(%eax),%eax
c010b2d1:	89 45 e0             	mov    %eax,-0x20(%ebp)
            arg[2] = tf->tf_regs.reg_ebx;
c010b2d4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b2d7:	8b 40 10             	mov    0x10(%eax),%eax
c010b2da:	89 45 e4             	mov    %eax,-0x1c(%ebp)
            arg[3] = tf->tf_regs.reg_edi;
c010b2dd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b2e0:	8b 00                	mov    (%eax),%eax
c010b2e2:	89 45 e8             	mov    %eax,-0x18(%ebp)
            arg[4] = tf->tf_regs.reg_esi;
c010b2e5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b2e8:	8b 40 04             	mov    0x4(%eax),%eax
c010b2eb:	89 45 ec             	mov    %eax,-0x14(%ebp)
            tf->tf_regs.reg_eax = syscalls[num](arg);
c010b2ee:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b2f1:	8b 04 85 a0 fa 12 c0 	mov    -0x3fed0560(,%eax,4),%eax
c010b2f8:	8d 55 dc             	lea    -0x24(%ebp),%edx
c010b2fb:	89 14 24             	mov    %edx,(%esp)
c010b2fe:	ff d0                	call   *%eax
c010b300:	89 c2                	mov    %eax,%edx
c010b302:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b305:	89 50 1c             	mov    %edx,0x1c(%eax)
            return ;
c010b308:	eb 46                	jmp    c010b350 <syscall+0xc4>
        }
    }
    print_trapframe(tf);
c010b30a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b30d:	89 04 24             	mov    %eax,(%esp)
c010b310:	e8 98 70 ff ff       	call   c01023ad <print_trapframe>
    //处理无效系统调用
    panic("undefined syscall %d, pid = %d, name = %s.\n",
c010b315:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010b31a:	8d 50 48             	lea    0x48(%eax),%edx
c010b31d:	a1 30 41 1a c0       	mov    0xc01a4130,%eax
c010b322:	8b 40 04             	mov    0x4(%eax),%eax
c010b325:	89 54 24 14          	mov    %edx,0x14(%esp)
c010b329:	89 44 24 10          	mov    %eax,0x10(%esp)
c010b32d:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b330:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010b334:	c7 44 24 08 0c e5 10 	movl   $0xc010e50c,0x8(%esp)
c010b33b:	c0 
c010b33c:	c7 44 24 04 69 00 00 	movl   $0x69,0x4(%esp)
c010b343:	00 
c010b344:	c7 04 24 38 e5 10 c0 	movl   $0xc010e538,(%esp)
c010b34b:	e8 eb 59 ff ff       	call   c0100d3b <__panic>
            num, current->pid, current->name);
}
c010b350:	89 ec                	mov    %ebp,%esp
c010b352:	5d                   	pop    %ebp
c010b353:	c3                   	ret    

c010b354 <hash32>:
 * @bits:   the number of bits in a return value
 *
 * High bits are more random, so we use them.
 * */
uint32_t
hash32(uint32_t val, unsigned int bits) {
c010b354:	55                   	push   %ebp
c010b355:	89 e5                	mov    %esp,%ebp
c010b357:	83 ec 10             	sub    $0x10,%esp
    uint32_t hash = val * GOLDEN_RATIO_PRIME_32;
c010b35a:	8b 45 08             	mov    0x8(%ebp),%eax
c010b35d:	69 c0 01 00 37 9e    	imul   $0x9e370001,%eax,%eax
c010b363:	89 45 fc             	mov    %eax,-0x4(%ebp)
    return (hash >> (32 - bits));
c010b366:	b8 20 00 00 00       	mov    $0x20,%eax
c010b36b:	2b 45 0c             	sub    0xc(%ebp),%eax
c010b36e:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010b371:	88 c1                	mov    %al,%cl
c010b373:	d3 ea                	shr    %cl,%edx
c010b375:	89 d0                	mov    %edx,%eax
}
c010b377:	89 ec                	mov    %ebp,%esp
c010b379:	5d                   	pop    %ebp
c010b37a:	c3                   	ret    

c010b37b <printnum>:
 * @width:      maximum number of digits, if the actual width is less than @width, use @padc instead
 * @padc:       character that padded on the left if the actual width is less than @width
 * */
static void
printnum(void (*putch)(int, void*), void *putdat,
        unsigned long long num, unsigned base, int width, int padc) {
c010b37b:	55                   	push   %ebp
c010b37c:	89 e5                	mov    %esp,%ebp
c010b37e:	83 ec 58             	sub    $0x58,%esp
c010b381:	8b 45 10             	mov    0x10(%ebp),%eax
c010b384:	89 45 d0             	mov    %eax,-0x30(%ebp)
c010b387:	8b 45 14             	mov    0x14(%ebp),%eax
c010b38a:	89 45 d4             	mov    %eax,-0x2c(%ebp)
    unsigned long long result = num;
c010b38d:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010b390:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010b393:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010b396:	89 55 ec             	mov    %edx,-0x14(%ebp)
    unsigned mod = do_div(result, base);
c010b399:	8b 45 18             	mov    0x18(%ebp),%eax
c010b39c:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c010b39f:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010b3a2:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010b3a5:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010b3a8:	89 55 f0             	mov    %edx,-0x10(%ebp)
c010b3ab:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b3ae:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010b3b1:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010b3b5:	74 1c                	je     c010b3d3 <printnum+0x58>
c010b3b7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b3ba:	ba 00 00 00 00       	mov    $0x0,%edx
c010b3bf:	f7 75 e4             	divl   -0x1c(%ebp)
c010b3c2:	89 55 f4             	mov    %edx,-0xc(%ebp)
c010b3c5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b3c8:	ba 00 00 00 00       	mov    $0x0,%edx
c010b3cd:	f7 75 e4             	divl   -0x1c(%ebp)
c010b3d0:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010b3d3:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010b3d6:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010b3d9:	f7 75 e4             	divl   -0x1c(%ebp)
c010b3dc:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010b3df:	89 55 dc             	mov    %edx,-0x24(%ebp)
c010b3e2:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010b3e5:	8b 55 f0             	mov    -0x10(%ebp),%edx
c010b3e8:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010b3eb:	89 55 ec             	mov    %edx,-0x14(%ebp)
c010b3ee:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010b3f1:	89 45 d8             	mov    %eax,-0x28(%ebp)

    // first recursively print all preceding (more significant) digits
    if (num >= base) {
c010b3f4:	8b 45 18             	mov    0x18(%ebp),%eax
c010b3f7:	ba 00 00 00 00       	mov    $0x0,%edx
c010b3fc:	8b 4d d4             	mov    -0x2c(%ebp),%ecx
c010b3ff:	39 45 d0             	cmp    %eax,-0x30(%ebp)
c010b402:	19 d1                	sbb    %edx,%ecx
c010b404:	72 4c                	jb     c010b452 <printnum+0xd7>
        printnum(putch, putdat, result, base, width - 1, padc);
c010b406:	8b 45 1c             	mov    0x1c(%ebp),%eax
c010b409:	8d 50 ff             	lea    -0x1(%eax),%edx
c010b40c:	8b 45 20             	mov    0x20(%ebp),%eax
c010b40f:	89 44 24 18          	mov    %eax,0x18(%esp)
c010b413:	89 54 24 14          	mov    %edx,0x14(%esp)
c010b417:	8b 45 18             	mov    0x18(%ebp),%eax
c010b41a:	89 44 24 10          	mov    %eax,0x10(%esp)
c010b41e:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010b421:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010b424:	89 44 24 08          	mov    %eax,0x8(%esp)
c010b428:	89 54 24 0c          	mov    %edx,0xc(%esp)
c010b42c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b42f:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b433:	8b 45 08             	mov    0x8(%ebp),%eax
c010b436:	89 04 24             	mov    %eax,(%esp)
c010b439:	e8 3d ff ff ff       	call   c010b37b <printnum>
c010b43e:	eb 1b                	jmp    c010b45b <printnum+0xe0>
    } else {
        // print any needed pad characters before first digit
        while (-- width > 0)
            putch(padc, putdat);
c010b440:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b443:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b447:	8b 45 20             	mov    0x20(%ebp),%eax
c010b44a:	89 04 24             	mov    %eax,(%esp)
c010b44d:	8b 45 08             	mov    0x8(%ebp),%eax
c010b450:	ff d0                	call   *%eax
        while (-- width > 0)
c010b452:	ff 4d 1c             	decl   0x1c(%ebp)
c010b455:	83 7d 1c 00          	cmpl   $0x0,0x1c(%ebp)
c010b459:	7f e5                	jg     c010b440 <printnum+0xc5>
    }
    // then print this (the least significant) digit
    putch("0123456789abcdef"[mod], putdat);
c010b45b:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010b45e:	05 64 e6 10 c0       	add    $0xc010e664,%eax
c010b463:	0f b6 00             	movzbl (%eax),%eax
c010b466:	0f be c0             	movsbl %al,%eax
c010b469:	8b 55 0c             	mov    0xc(%ebp),%edx
c010b46c:	89 54 24 04          	mov    %edx,0x4(%esp)
c010b470:	89 04 24             	mov    %eax,(%esp)
c010b473:	8b 45 08             	mov    0x8(%ebp),%eax
c010b476:	ff d0                	call   *%eax
}
c010b478:	90                   	nop
c010b479:	89 ec                	mov    %ebp,%esp
c010b47b:	5d                   	pop    %ebp
c010b47c:	c3                   	ret    

c010b47d <getuint>:
 * getuint - get an unsigned int of various possible sizes from a varargs list
 * @ap:         a varargs list pointer
 * @lflag:      determines the size of the vararg that @ap points to
 * */
static unsigned long long
getuint(va_list *ap, int lflag) {
c010b47d:	55                   	push   %ebp
c010b47e:	89 e5                	mov    %esp,%ebp
    if (lflag >= 2) {
c010b480:	83 7d 0c 01          	cmpl   $0x1,0xc(%ebp)
c010b484:	7e 14                	jle    c010b49a <getuint+0x1d>
        return va_arg(*ap, unsigned long long);
c010b486:	8b 45 08             	mov    0x8(%ebp),%eax
c010b489:	8b 00                	mov    (%eax),%eax
c010b48b:	8d 48 08             	lea    0x8(%eax),%ecx
c010b48e:	8b 55 08             	mov    0x8(%ebp),%edx
c010b491:	89 0a                	mov    %ecx,(%edx)
c010b493:	8b 50 04             	mov    0x4(%eax),%edx
c010b496:	8b 00                	mov    (%eax),%eax
c010b498:	eb 30                	jmp    c010b4ca <getuint+0x4d>
    }
    else if (lflag) {
c010b49a:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010b49e:	74 16                	je     c010b4b6 <getuint+0x39>
        return va_arg(*ap, unsigned long);
c010b4a0:	8b 45 08             	mov    0x8(%ebp),%eax
c010b4a3:	8b 00                	mov    (%eax),%eax
c010b4a5:	8d 48 04             	lea    0x4(%eax),%ecx
c010b4a8:	8b 55 08             	mov    0x8(%ebp),%edx
c010b4ab:	89 0a                	mov    %ecx,(%edx)
c010b4ad:	8b 00                	mov    (%eax),%eax
c010b4af:	ba 00 00 00 00       	mov    $0x0,%edx
c010b4b4:	eb 14                	jmp    c010b4ca <getuint+0x4d>
    }
    else {
        return va_arg(*ap, unsigned int);
c010b4b6:	8b 45 08             	mov    0x8(%ebp),%eax
c010b4b9:	8b 00                	mov    (%eax),%eax
c010b4bb:	8d 48 04             	lea    0x4(%eax),%ecx
c010b4be:	8b 55 08             	mov    0x8(%ebp),%edx
c010b4c1:	89 0a                	mov    %ecx,(%edx)
c010b4c3:	8b 00                	mov    (%eax),%eax
c010b4c5:	ba 00 00 00 00       	mov    $0x0,%edx
    }
}
c010b4ca:	5d                   	pop    %ebp
c010b4cb:	c3                   	ret    

c010b4cc <getint>:
 * getint - same as getuint but signed, we can't use getuint because of sign extension
 * @ap:         a varargs list pointer
 * @lflag:      determines the size of the vararg that @ap points to
 * */
static long long
getint(va_list *ap, int lflag) {
c010b4cc:	55                   	push   %ebp
c010b4cd:	89 e5                	mov    %esp,%ebp
    if (lflag >= 2) {
c010b4cf:	83 7d 0c 01          	cmpl   $0x1,0xc(%ebp)
c010b4d3:	7e 14                	jle    c010b4e9 <getint+0x1d>
        return va_arg(*ap, long long);
c010b4d5:	8b 45 08             	mov    0x8(%ebp),%eax
c010b4d8:	8b 00                	mov    (%eax),%eax
c010b4da:	8d 48 08             	lea    0x8(%eax),%ecx
c010b4dd:	8b 55 08             	mov    0x8(%ebp),%edx
c010b4e0:	89 0a                	mov    %ecx,(%edx)
c010b4e2:	8b 50 04             	mov    0x4(%eax),%edx
c010b4e5:	8b 00                	mov    (%eax),%eax
c010b4e7:	eb 28                	jmp    c010b511 <getint+0x45>
    }
    else if (lflag) {
c010b4e9:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010b4ed:	74 12                	je     c010b501 <getint+0x35>
        return va_arg(*ap, long);
c010b4ef:	8b 45 08             	mov    0x8(%ebp),%eax
c010b4f2:	8b 00                	mov    (%eax),%eax
c010b4f4:	8d 48 04             	lea    0x4(%eax),%ecx
c010b4f7:	8b 55 08             	mov    0x8(%ebp),%edx
c010b4fa:	89 0a                	mov    %ecx,(%edx)
c010b4fc:	8b 00                	mov    (%eax),%eax
c010b4fe:	99                   	cltd   
c010b4ff:	eb 10                	jmp    c010b511 <getint+0x45>
    }
    else {
        return va_arg(*ap, int);
c010b501:	8b 45 08             	mov    0x8(%ebp),%eax
c010b504:	8b 00                	mov    (%eax),%eax
c010b506:	8d 48 04             	lea    0x4(%eax),%ecx
c010b509:	8b 55 08             	mov    0x8(%ebp),%edx
c010b50c:	89 0a                	mov    %ecx,(%edx)
c010b50e:	8b 00                	mov    (%eax),%eax
c010b510:	99                   	cltd   
    }
}
c010b511:	5d                   	pop    %ebp
c010b512:	c3                   	ret    

c010b513 <printfmt>:
 * @putch:      specified putch function, print a single character
 * @putdat:     used by @putch function
 * @fmt:        the format string to use
 * */
void
printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) {
c010b513:	55                   	push   %ebp
c010b514:	89 e5                	mov    %esp,%ebp
c010b516:	83 ec 28             	sub    $0x28,%esp
    va_list ap;

    va_start(ap, fmt);
c010b519:	8d 45 14             	lea    0x14(%ebp),%eax
c010b51c:	89 45 f4             	mov    %eax,-0xc(%ebp)
    vprintfmt(putch, putdat, fmt, ap);
c010b51f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010b522:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010b526:	8b 45 10             	mov    0x10(%ebp),%eax
c010b529:	89 44 24 08          	mov    %eax,0x8(%esp)
c010b52d:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b530:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b534:	8b 45 08             	mov    0x8(%ebp),%eax
c010b537:	89 04 24             	mov    %eax,(%esp)
c010b53a:	e8 05 00 00 00       	call   c010b544 <vprintfmt>
    va_end(ap);
}
c010b53f:	90                   	nop
c010b540:	89 ec                	mov    %ebp,%esp
c010b542:	5d                   	pop    %ebp
c010b543:	c3                   	ret    

c010b544 <vprintfmt>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want printfmt() instead.
 * */
void
vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) {
c010b544:	55                   	push   %ebp
c010b545:	89 e5                	mov    %esp,%ebp
c010b547:	56                   	push   %esi
c010b548:	53                   	push   %ebx
c010b549:	83 ec 40             	sub    $0x40,%esp
    register int ch, err;
    unsigned long long num;
    int base, width, precision, lflag, altflag;

    while (1) {
        while ((ch = *(unsigned char *)fmt ++) != '%') {
c010b54c:	eb 17                	jmp    c010b565 <vprintfmt+0x21>
            if (ch == '\0') {
c010b54e:	85 db                	test   %ebx,%ebx
c010b550:	0f 84 bf 03 00 00    	je     c010b915 <vprintfmt+0x3d1>
                return;
            }
            putch(ch, putdat);
c010b556:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b559:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b55d:	89 1c 24             	mov    %ebx,(%esp)
c010b560:	8b 45 08             	mov    0x8(%ebp),%eax
c010b563:	ff d0                	call   *%eax
        while ((ch = *(unsigned char *)fmt ++) != '%') {
c010b565:	8b 45 10             	mov    0x10(%ebp),%eax
c010b568:	8d 50 01             	lea    0x1(%eax),%edx
c010b56b:	89 55 10             	mov    %edx,0x10(%ebp)
c010b56e:	0f b6 00             	movzbl (%eax),%eax
c010b571:	0f b6 d8             	movzbl %al,%ebx
c010b574:	83 fb 25             	cmp    $0x25,%ebx
c010b577:	75 d5                	jne    c010b54e <vprintfmt+0xa>
        }

        // Process a %-escape sequence
        char padc = ' ';
c010b579:	c6 45 db 20          	movb   $0x20,-0x25(%ebp)
        width = precision = -1;
c010b57d:	c7 45 e4 ff ff ff ff 	movl   $0xffffffff,-0x1c(%ebp)
c010b584:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010b587:	89 45 e8             	mov    %eax,-0x18(%ebp)
        lflag = altflag = 0;
c010b58a:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c010b591:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010b594:	89 45 e0             	mov    %eax,-0x20(%ebp)

    reswitch:
        switch (ch = *(unsigned char *)fmt ++) {
c010b597:	8b 45 10             	mov    0x10(%ebp),%eax
c010b59a:	8d 50 01             	lea    0x1(%eax),%edx
c010b59d:	89 55 10             	mov    %edx,0x10(%ebp)
c010b5a0:	0f b6 00             	movzbl (%eax),%eax
c010b5a3:	0f b6 d8             	movzbl %al,%ebx
c010b5a6:	8d 43 dd             	lea    -0x23(%ebx),%eax
c010b5a9:	83 f8 55             	cmp    $0x55,%eax
c010b5ac:	0f 87 37 03 00 00    	ja     c010b8e9 <vprintfmt+0x3a5>
c010b5b2:	8b 04 85 88 e6 10 c0 	mov    -0x3fef1978(,%eax,4),%eax
c010b5b9:	ff e0                	jmp    *%eax

        // flag to pad on the right
        case '-':
            padc = '-';
c010b5bb:	c6 45 db 2d          	movb   $0x2d,-0x25(%ebp)
            goto reswitch;
c010b5bf:	eb d6                	jmp    c010b597 <vprintfmt+0x53>

        // flag to pad with 0's instead of spaces
        case '0':
            padc = '0';
c010b5c1:	c6 45 db 30          	movb   $0x30,-0x25(%ebp)
            goto reswitch;
c010b5c5:	eb d0                	jmp    c010b597 <vprintfmt+0x53>

        // width field
        case '1' ... '9':
            for (precision = 0; ; ++ fmt) {
c010b5c7:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
                precision = precision * 10 + ch - '0';
c010b5ce:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010b5d1:	89 d0                	mov    %edx,%eax
c010b5d3:	c1 e0 02             	shl    $0x2,%eax
c010b5d6:	01 d0                	add    %edx,%eax
c010b5d8:	01 c0                	add    %eax,%eax
c010b5da:	01 d8                	add    %ebx,%eax
c010b5dc:	83 e8 30             	sub    $0x30,%eax
c010b5df:	89 45 e4             	mov    %eax,-0x1c(%ebp)
                ch = *fmt;
c010b5e2:	8b 45 10             	mov    0x10(%ebp),%eax
c010b5e5:	0f b6 00             	movzbl (%eax),%eax
c010b5e8:	0f be d8             	movsbl %al,%ebx
                if (ch < '0' || ch > '9') {
c010b5eb:	83 fb 2f             	cmp    $0x2f,%ebx
c010b5ee:	7e 38                	jle    c010b628 <vprintfmt+0xe4>
c010b5f0:	83 fb 39             	cmp    $0x39,%ebx
c010b5f3:	7f 33                	jg     c010b628 <vprintfmt+0xe4>
            for (precision = 0; ; ++ fmt) {
c010b5f5:	ff 45 10             	incl   0x10(%ebp)
                precision = precision * 10 + ch - '0';
c010b5f8:	eb d4                	jmp    c010b5ce <vprintfmt+0x8a>
                }
            }
            goto process_precision;

        case '*':
            precision = va_arg(ap, int);
c010b5fa:	8b 45 14             	mov    0x14(%ebp),%eax
c010b5fd:	8d 50 04             	lea    0x4(%eax),%edx
c010b600:	89 55 14             	mov    %edx,0x14(%ebp)
c010b603:	8b 00                	mov    (%eax),%eax
c010b605:	89 45 e4             	mov    %eax,-0x1c(%ebp)
            goto process_precision;
c010b608:	eb 1f                	jmp    c010b629 <vprintfmt+0xe5>

        case '.':
            if (width < 0)
c010b60a:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010b60e:	79 87                	jns    c010b597 <vprintfmt+0x53>
                width = 0;
c010b610:	c7 45 e8 00 00 00 00 	movl   $0x0,-0x18(%ebp)
            goto reswitch;
c010b617:	e9 7b ff ff ff       	jmp    c010b597 <vprintfmt+0x53>

        case '#':
            altflag = 1;
c010b61c:	c7 45 dc 01 00 00 00 	movl   $0x1,-0x24(%ebp)
            goto reswitch;
c010b623:	e9 6f ff ff ff       	jmp    c010b597 <vprintfmt+0x53>
            goto process_precision;
c010b628:	90                   	nop

        process_precision:
            if (width < 0)
c010b629:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010b62d:	0f 89 64 ff ff ff    	jns    c010b597 <vprintfmt+0x53>
                width = precision, precision = -1;
c010b633:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010b636:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010b639:	c7 45 e4 ff ff ff ff 	movl   $0xffffffff,-0x1c(%ebp)
            goto reswitch;
c010b640:	e9 52 ff ff ff       	jmp    c010b597 <vprintfmt+0x53>

        // long flag (doubled for long long)
        case 'l':
            lflag ++;
c010b645:	ff 45 e0             	incl   -0x20(%ebp)
            goto reswitch;
c010b648:	e9 4a ff ff ff       	jmp    c010b597 <vprintfmt+0x53>

        // character
        case 'c':
            putch(va_arg(ap, int), putdat);
c010b64d:	8b 45 14             	mov    0x14(%ebp),%eax
c010b650:	8d 50 04             	lea    0x4(%eax),%edx
c010b653:	89 55 14             	mov    %edx,0x14(%ebp)
c010b656:	8b 00                	mov    (%eax),%eax
c010b658:	8b 55 0c             	mov    0xc(%ebp),%edx
c010b65b:	89 54 24 04          	mov    %edx,0x4(%esp)
c010b65f:	89 04 24             	mov    %eax,(%esp)
c010b662:	8b 45 08             	mov    0x8(%ebp),%eax
c010b665:	ff d0                	call   *%eax
            break;
c010b667:	e9 a4 02 00 00       	jmp    c010b910 <vprintfmt+0x3cc>

        // error message
        case 'e':
            err = va_arg(ap, int);
c010b66c:	8b 45 14             	mov    0x14(%ebp),%eax
c010b66f:	8d 50 04             	lea    0x4(%eax),%edx
c010b672:	89 55 14             	mov    %edx,0x14(%ebp)
c010b675:	8b 18                	mov    (%eax),%ebx
            if (err < 0) {
c010b677:	85 db                	test   %ebx,%ebx
c010b679:	79 02                	jns    c010b67d <vprintfmt+0x139>
                err = -err;
c010b67b:	f7 db                	neg    %ebx
            }
            if (err > MAXERROR || (p = error_string[err]) == NULL) {
c010b67d:	83 fb 18             	cmp    $0x18,%ebx
c010b680:	7f 0b                	jg     c010b68d <vprintfmt+0x149>
c010b682:	8b 34 9d 00 e6 10 c0 	mov    -0x3fef1a00(,%ebx,4),%esi
c010b689:	85 f6                	test   %esi,%esi
c010b68b:	75 23                	jne    c010b6b0 <vprintfmt+0x16c>
                printfmt(putch, putdat, "error %d", err);
c010b68d:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c010b691:	c7 44 24 08 75 e6 10 	movl   $0xc010e675,0x8(%esp)
c010b698:	c0 
c010b699:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b69c:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b6a0:	8b 45 08             	mov    0x8(%ebp),%eax
c010b6a3:	89 04 24             	mov    %eax,(%esp)
c010b6a6:	e8 68 fe ff ff       	call   c010b513 <printfmt>
            }
            else {
                printfmt(putch, putdat, "%s", p);
            }
            break;
c010b6ab:	e9 60 02 00 00       	jmp    c010b910 <vprintfmt+0x3cc>
                printfmt(putch, putdat, "%s", p);
c010b6b0:	89 74 24 0c          	mov    %esi,0xc(%esp)
c010b6b4:	c7 44 24 08 7e e6 10 	movl   $0xc010e67e,0x8(%esp)
c010b6bb:	c0 
c010b6bc:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b6bf:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b6c3:	8b 45 08             	mov    0x8(%ebp),%eax
c010b6c6:	89 04 24             	mov    %eax,(%esp)
c010b6c9:	e8 45 fe ff ff       	call   c010b513 <printfmt>
            break;
c010b6ce:	e9 3d 02 00 00       	jmp    c010b910 <vprintfmt+0x3cc>

        // string
        case 's':
            if ((p = va_arg(ap, char *)) == NULL) {
c010b6d3:	8b 45 14             	mov    0x14(%ebp),%eax
c010b6d6:	8d 50 04             	lea    0x4(%eax),%edx
c010b6d9:	89 55 14             	mov    %edx,0x14(%ebp)
c010b6dc:	8b 30                	mov    (%eax),%esi
c010b6de:	85 f6                	test   %esi,%esi
c010b6e0:	75 05                	jne    c010b6e7 <vprintfmt+0x1a3>
                p = "(null)";
c010b6e2:	be 81 e6 10 c0       	mov    $0xc010e681,%esi
            }
            if (width > 0 && padc != '-') {
c010b6e7:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010b6eb:	7e 76                	jle    c010b763 <vprintfmt+0x21f>
c010b6ed:	80 7d db 2d          	cmpb   $0x2d,-0x25(%ebp)
c010b6f1:	74 70                	je     c010b763 <vprintfmt+0x21f>
                for (width -= strnlen(p, precision); width > 0; width --) {
c010b6f3:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010b6f6:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b6fa:	89 34 24             	mov    %esi,(%esp)
c010b6fd:	e8 ee 03 00 00       	call   c010baf0 <strnlen>
c010b702:	89 c2                	mov    %eax,%edx
c010b704:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010b707:	29 d0                	sub    %edx,%eax
c010b709:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010b70c:	eb 16                	jmp    c010b724 <vprintfmt+0x1e0>
                    putch(padc, putdat);
c010b70e:	0f be 45 db          	movsbl -0x25(%ebp),%eax
c010b712:	8b 55 0c             	mov    0xc(%ebp),%edx
c010b715:	89 54 24 04          	mov    %edx,0x4(%esp)
c010b719:	89 04 24             	mov    %eax,(%esp)
c010b71c:	8b 45 08             	mov    0x8(%ebp),%eax
c010b71f:	ff d0                	call   *%eax
                for (width -= strnlen(p, precision); width > 0; width --) {
c010b721:	ff 4d e8             	decl   -0x18(%ebp)
c010b724:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010b728:	7f e4                	jg     c010b70e <vprintfmt+0x1ca>
                }
            }
            for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) {
c010b72a:	eb 37                	jmp    c010b763 <vprintfmt+0x21f>
                if (altflag && (ch < ' ' || ch > '~')) {
c010b72c:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c010b730:	74 1f                	je     c010b751 <vprintfmt+0x20d>
c010b732:	83 fb 1f             	cmp    $0x1f,%ebx
c010b735:	7e 05                	jle    c010b73c <vprintfmt+0x1f8>
c010b737:	83 fb 7e             	cmp    $0x7e,%ebx
c010b73a:	7e 15                	jle    c010b751 <vprintfmt+0x20d>
                    putch('?', putdat);
c010b73c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b73f:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b743:	c7 04 24 3f 00 00 00 	movl   $0x3f,(%esp)
c010b74a:	8b 45 08             	mov    0x8(%ebp),%eax
c010b74d:	ff d0                	call   *%eax
c010b74f:	eb 0f                	jmp    c010b760 <vprintfmt+0x21c>
                }
                else {
                    putch(ch, putdat);
c010b751:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b754:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b758:	89 1c 24             	mov    %ebx,(%esp)
c010b75b:	8b 45 08             	mov    0x8(%ebp),%eax
c010b75e:	ff d0                	call   *%eax
            for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) {
c010b760:	ff 4d e8             	decl   -0x18(%ebp)
c010b763:	89 f0                	mov    %esi,%eax
c010b765:	8d 70 01             	lea    0x1(%eax),%esi
c010b768:	0f b6 00             	movzbl (%eax),%eax
c010b76b:	0f be d8             	movsbl %al,%ebx
c010b76e:	85 db                	test   %ebx,%ebx
c010b770:	74 27                	je     c010b799 <vprintfmt+0x255>
c010b772:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c010b776:	78 b4                	js     c010b72c <vprintfmt+0x1e8>
c010b778:	ff 4d e4             	decl   -0x1c(%ebp)
c010b77b:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c010b77f:	79 ab                	jns    c010b72c <vprintfmt+0x1e8>
                }
            }
            for (; width > 0; width --) {
c010b781:	eb 16                	jmp    c010b799 <vprintfmt+0x255>
                putch(' ', putdat);
c010b783:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b786:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b78a:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c010b791:	8b 45 08             	mov    0x8(%ebp),%eax
c010b794:	ff d0                	call   *%eax
            for (; width > 0; width --) {
c010b796:	ff 4d e8             	decl   -0x18(%ebp)
c010b799:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010b79d:	7f e4                	jg     c010b783 <vprintfmt+0x23f>
            }
            break;
c010b79f:	e9 6c 01 00 00       	jmp    c010b910 <vprintfmt+0x3cc>

        // (signed) decimal
        case 'd':
            num = getint(&ap, lflag);
c010b7a4:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010b7a7:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b7ab:	8d 45 14             	lea    0x14(%ebp),%eax
c010b7ae:	89 04 24             	mov    %eax,(%esp)
c010b7b1:	e8 16 fd ff ff       	call   c010b4cc <getint>
c010b7b6:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010b7b9:	89 55 f4             	mov    %edx,-0xc(%ebp)
            if ((long long)num < 0) {
c010b7bc:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b7bf:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010b7c2:	85 d2                	test   %edx,%edx
c010b7c4:	79 26                	jns    c010b7ec <vprintfmt+0x2a8>
                putch('-', putdat);
c010b7c6:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b7c9:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b7cd:	c7 04 24 2d 00 00 00 	movl   $0x2d,(%esp)
c010b7d4:	8b 45 08             	mov    0x8(%ebp),%eax
c010b7d7:	ff d0                	call   *%eax
                num = -(long long)num;
c010b7d9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b7dc:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010b7df:	f7 d8                	neg    %eax
c010b7e1:	83 d2 00             	adc    $0x0,%edx
c010b7e4:	f7 da                	neg    %edx
c010b7e6:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010b7e9:	89 55 f4             	mov    %edx,-0xc(%ebp)
            }
            base = 10;
c010b7ec:	c7 45 ec 0a 00 00 00 	movl   $0xa,-0x14(%ebp)
            goto number;
c010b7f3:	e9 a8 00 00 00       	jmp    c010b8a0 <vprintfmt+0x35c>

        // unsigned decimal
        case 'u':
            num = getuint(&ap, lflag);
c010b7f8:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010b7fb:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b7ff:	8d 45 14             	lea    0x14(%ebp),%eax
c010b802:	89 04 24             	mov    %eax,(%esp)
c010b805:	e8 73 fc ff ff       	call   c010b47d <getuint>
c010b80a:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010b80d:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 10;
c010b810:	c7 45 ec 0a 00 00 00 	movl   $0xa,-0x14(%ebp)
            goto number;
c010b817:	e9 84 00 00 00       	jmp    c010b8a0 <vprintfmt+0x35c>

        // (unsigned) octal
        case 'o':
            num = getuint(&ap, lflag);
c010b81c:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010b81f:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b823:	8d 45 14             	lea    0x14(%ebp),%eax
c010b826:	89 04 24             	mov    %eax,(%esp)
c010b829:	e8 4f fc ff ff       	call   c010b47d <getuint>
c010b82e:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010b831:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 8;
c010b834:	c7 45 ec 08 00 00 00 	movl   $0x8,-0x14(%ebp)
            goto number;
c010b83b:	eb 63                	jmp    c010b8a0 <vprintfmt+0x35c>

        // pointer
        case 'p':
            putch('0', putdat);
c010b83d:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b840:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b844:	c7 04 24 30 00 00 00 	movl   $0x30,(%esp)
c010b84b:	8b 45 08             	mov    0x8(%ebp),%eax
c010b84e:	ff d0                	call   *%eax
            putch('x', putdat);
c010b850:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b853:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b857:	c7 04 24 78 00 00 00 	movl   $0x78,(%esp)
c010b85e:	8b 45 08             	mov    0x8(%ebp),%eax
c010b861:	ff d0                	call   *%eax
            num = (unsigned long long)(uintptr_t)va_arg(ap, void *);
c010b863:	8b 45 14             	mov    0x14(%ebp),%eax
c010b866:	8d 50 04             	lea    0x4(%eax),%edx
c010b869:	89 55 14             	mov    %edx,0x14(%ebp)
c010b86c:	8b 00                	mov    (%eax),%eax
c010b86e:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010b871:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
            base = 16;
c010b878:	c7 45 ec 10 00 00 00 	movl   $0x10,-0x14(%ebp)
            goto number;
c010b87f:	eb 1f                	jmp    c010b8a0 <vprintfmt+0x35c>

        // (unsigned) hexadecimal
        case 'x':
            num = getuint(&ap, lflag);
c010b881:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010b884:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b888:	8d 45 14             	lea    0x14(%ebp),%eax
c010b88b:	89 04 24             	mov    %eax,(%esp)
c010b88e:	e8 ea fb ff ff       	call   c010b47d <getuint>
c010b893:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010b896:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 16;
c010b899:	c7 45 ec 10 00 00 00 	movl   $0x10,-0x14(%ebp)
        number:
            printnum(putch, putdat, num, base, width, padc);
c010b8a0:	0f be 55 db          	movsbl -0x25(%ebp),%edx
c010b8a4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010b8a7:	89 54 24 18          	mov    %edx,0x18(%esp)
c010b8ab:	8b 55 e8             	mov    -0x18(%ebp),%edx
c010b8ae:	89 54 24 14          	mov    %edx,0x14(%esp)
c010b8b2:	89 44 24 10          	mov    %eax,0x10(%esp)
c010b8b6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b8b9:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010b8bc:	89 44 24 08          	mov    %eax,0x8(%esp)
c010b8c0:	89 54 24 0c          	mov    %edx,0xc(%esp)
c010b8c4:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b8c7:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b8cb:	8b 45 08             	mov    0x8(%ebp),%eax
c010b8ce:	89 04 24             	mov    %eax,(%esp)
c010b8d1:	e8 a5 fa ff ff       	call   c010b37b <printnum>
            break;
c010b8d6:	eb 38                	jmp    c010b910 <vprintfmt+0x3cc>

        // escaped '%' character
        case '%':
            putch(ch, putdat);
c010b8d8:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b8db:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b8df:	89 1c 24             	mov    %ebx,(%esp)
c010b8e2:	8b 45 08             	mov    0x8(%ebp),%eax
c010b8e5:	ff d0                	call   *%eax
            break;
c010b8e7:	eb 27                	jmp    c010b910 <vprintfmt+0x3cc>

        // unrecognized escape sequence - just print it literally
        default:
            putch('%', putdat);
c010b8e9:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b8ec:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b8f0:	c7 04 24 25 00 00 00 	movl   $0x25,(%esp)
c010b8f7:	8b 45 08             	mov    0x8(%ebp),%eax
c010b8fa:	ff d0                	call   *%eax
            for (fmt --; fmt[-1] != '%'; fmt --)
c010b8fc:	ff 4d 10             	decl   0x10(%ebp)
c010b8ff:	eb 03                	jmp    c010b904 <vprintfmt+0x3c0>
c010b901:	ff 4d 10             	decl   0x10(%ebp)
c010b904:	8b 45 10             	mov    0x10(%ebp),%eax
c010b907:	48                   	dec    %eax
c010b908:	0f b6 00             	movzbl (%eax),%eax
c010b90b:	3c 25                	cmp    $0x25,%al
c010b90d:	75 f2                	jne    c010b901 <vprintfmt+0x3bd>
                /* do nothing */;
            break;
c010b90f:	90                   	nop
    while (1) {
c010b910:	e9 37 fc ff ff       	jmp    c010b54c <vprintfmt+0x8>
                return;
c010b915:	90                   	nop
        }
    }
}
c010b916:	83 c4 40             	add    $0x40,%esp
c010b919:	5b                   	pop    %ebx
c010b91a:	5e                   	pop    %esi
c010b91b:	5d                   	pop    %ebp
c010b91c:	c3                   	ret    

c010b91d <sprintputch>:
 * sprintputch - 'print' a single character in a buffer
 * @ch:         the character will be printed
 * @b:          the buffer to place the character @ch
 * */
static void
sprintputch(int ch, struct sprintbuf *b) {
c010b91d:	55                   	push   %ebp
c010b91e:	89 e5                	mov    %esp,%ebp
    b->cnt ++;
c010b920:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b923:	8b 40 08             	mov    0x8(%eax),%eax
c010b926:	8d 50 01             	lea    0x1(%eax),%edx
c010b929:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b92c:	89 50 08             	mov    %edx,0x8(%eax)
    if (b->buf < b->ebuf) {
c010b92f:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b932:	8b 10                	mov    (%eax),%edx
c010b934:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b937:	8b 40 04             	mov    0x4(%eax),%eax
c010b93a:	39 c2                	cmp    %eax,%edx
c010b93c:	73 12                	jae    c010b950 <sprintputch+0x33>
        *b->buf ++ = ch;
c010b93e:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b941:	8b 00                	mov    (%eax),%eax
c010b943:	8d 48 01             	lea    0x1(%eax),%ecx
c010b946:	8b 55 0c             	mov    0xc(%ebp),%edx
c010b949:	89 0a                	mov    %ecx,(%edx)
c010b94b:	8b 55 08             	mov    0x8(%ebp),%edx
c010b94e:	88 10                	mov    %dl,(%eax)
    }
}
c010b950:	90                   	nop
c010b951:	5d                   	pop    %ebp
c010b952:	c3                   	ret    

c010b953 <snprintf>:
 * @str:        the buffer to place the result into
 * @size:       the size of buffer, including the trailing null space
 * @fmt:        the format string to use
 * */
int
snprintf(char *str, size_t size, const char *fmt, ...) {
c010b953:	55                   	push   %ebp
c010b954:	89 e5                	mov    %esp,%ebp
c010b956:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    int cnt;
    va_start(ap, fmt);
c010b959:	8d 45 14             	lea    0x14(%ebp),%eax
c010b95c:	89 45 f0             	mov    %eax,-0x10(%ebp)
    cnt = vsnprintf(str, size, fmt, ap);
c010b95f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b962:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010b966:	8b 45 10             	mov    0x10(%ebp),%eax
c010b969:	89 44 24 08          	mov    %eax,0x8(%esp)
c010b96d:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b970:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b974:	8b 45 08             	mov    0x8(%ebp),%eax
c010b977:	89 04 24             	mov    %eax,(%esp)
c010b97a:	e8 0a 00 00 00       	call   c010b989 <vsnprintf>
c010b97f:	89 45 f4             	mov    %eax,-0xc(%ebp)
    va_end(ap);
    return cnt;
c010b982:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010b985:	89 ec                	mov    %ebp,%esp
c010b987:	5d                   	pop    %ebp
c010b988:	c3                   	ret    

c010b989 <vsnprintf>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want snprintf() instead.
 * */
int
vsnprintf(char *str, size_t size, const char *fmt, va_list ap) {
c010b989:	55                   	push   %ebp
c010b98a:	89 e5                	mov    %esp,%ebp
c010b98c:	83 ec 28             	sub    $0x28,%esp
    struct sprintbuf b = {str, str + size - 1, 0};
c010b98f:	8b 45 08             	mov    0x8(%ebp),%eax
c010b992:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010b995:	8b 45 0c             	mov    0xc(%ebp),%eax
c010b998:	8d 50 ff             	lea    -0x1(%eax),%edx
c010b99b:	8b 45 08             	mov    0x8(%ebp),%eax
c010b99e:	01 d0                	add    %edx,%eax
c010b9a0:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010b9a3:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    if (str == NULL || b.buf > b.ebuf) {
c010b9aa:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c010b9ae:	74 0a                	je     c010b9ba <vsnprintf+0x31>
c010b9b0:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010b9b3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010b9b6:	39 c2                	cmp    %eax,%edx
c010b9b8:	76 07                	jbe    c010b9c1 <vsnprintf+0x38>
        return -E_INVAL;
c010b9ba:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
c010b9bf:	eb 2a                	jmp    c010b9eb <vsnprintf+0x62>
    }
    // print the string to the buffer
    vprintfmt((void*)sprintputch, &b, fmt, ap);
c010b9c1:	8b 45 14             	mov    0x14(%ebp),%eax
c010b9c4:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010b9c8:	8b 45 10             	mov    0x10(%ebp),%eax
c010b9cb:	89 44 24 08          	mov    %eax,0x8(%esp)
c010b9cf:	8d 45 ec             	lea    -0x14(%ebp),%eax
c010b9d2:	89 44 24 04          	mov    %eax,0x4(%esp)
c010b9d6:	c7 04 24 1d b9 10 c0 	movl   $0xc010b91d,(%esp)
c010b9dd:	e8 62 fb ff ff       	call   c010b544 <vprintfmt>
    // null terminate the buffer
    *b.buf = '\0';
c010b9e2:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010b9e5:	c6 00 00             	movb   $0x0,(%eax)
    return b.cnt;
c010b9e8:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010b9eb:	89 ec                	mov    %ebp,%esp
c010b9ed:	5d                   	pop    %ebp
c010b9ee:	c3                   	ret    

c010b9ef <rand>:
 * rand - returns a pseudo-random integer
 *
 * The rand() function return a value in the range [0, RAND_MAX].
 * */
int
rand(void) {
c010b9ef:	55                   	push   %ebp
c010b9f0:	89 e5                	mov    %esp,%ebp
c010b9f2:	57                   	push   %edi
c010b9f3:	56                   	push   %esi
c010b9f4:	53                   	push   %ebx
c010b9f5:	83 ec 24             	sub    $0x24,%esp
    next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1);
c010b9f8:	a1 20 fb 12 c0       	mov    0xc012fb20,%eax
c010b9fd:	8b 15 24 fb 12 c0    	mov    0xc012fb24,%edx
c010ba03:	69 fa 6d e6 ec de    	imul   $0xdeece66d,%edx,%edi
c010ba09:	6b f0 05             	imul   $0x5,%eax,%esi
c010ba0c:	01 fe                	add    %edi,%esi
c010ba0e:	bf 6d e6 ec de       	mov    $0xdeece66d,%edi
c010ba13:	f7 e7                	mul    %edi
c010ba15:	01 d6                	add    %edx,%esi
c010ba17:	89 f2                	mov    %esi,%edx
c010ba19:	83 c0 0b             	add    $0xb,%eax
c010ba1c:	83 d2 00             	adc    $0x0,%edx
c010ba1f:	89 c7                	mov    %eax,%edi
c010ba21:	83 e7 ff             	and    $0xffffffff,%edi
c010ba24:	89 f9                	mov    %edi,%ecx
c010ba26:	0f b7 da             	movzwl %dx,%ebx
c010ba29:	89 0d 20 fb 12 c0    	mov    %ecx,0xc012fb20
c010ba2f:	89 1d 24 fb 12 c0    	mov    %ebx,0xc012fb24
    unsigned long long result = (next >> 12);
c010ba35:	a1 20 fb 12 c0       	mov    0xc012fb20,%eax
c010ba3a:	8b 15 24 fb 12 c0    	mov    0xc012fb24,%edx
c010ba40:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c010ba44:	c1 ea 0c             	shr    $0xc,%edx
c010ba47:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010ba4a:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    return (int)do_div(result, RAND_MAX + 1);
c010ba4d:	c7 45 dc 00 00 00 80 	movl   $0x80000000,-0x24(%ebp)
c010ba54:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010ba57:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010ba5a:	89 45 d8             	mov    %eax,-0x28(%ebp)
c010ba5d:	89 55 e8             	mov    %edx,-0x18(%ebp)
c010ba60:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010ba63:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010ba66:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010ba6a:	74 1c                	je     c010ba88 <rand+0x99>
c010ba6c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010ba6f:	ba 00 00 00 00       	mov    $0x0,%edx
c010ba74:	f7 75 dc             	divl   -0x24(%ebp)
c010ba77:	89 55 ec             	mov    %edx,-0x14(%ebp)
c010ba7a:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010ba7d:	ba 00 00 00 00       	mov    $0x0,%edx
c010ba82:	f7 75 dc             	divl   -0x24(%ebp)
c010ba85:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010ba88:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010ba8b:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010ba8e:	f7 75 dc             	divl   -0x24(%ebp)
c010ba91:	89 45 d8             	mov    %eax,-0x28(%ebp)
c010ba94:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c010ba97:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010ba9a:	8b 55 e8             	mov    -0x18(%ebp),%edx
c010ba9d:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010baa0:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c010baa3:	8b 45 d4             	mov    -0x2c(%ebp),%eax
}
c010baa6:	83 c4 24             	add    $0x24,%esp
c010baa9:	5b                   	pop    %ebx
c010baaa:	5e                   	pop    %esi
c010baab:	5f                   	pop    %edi
c010baac:	5d                   	pop    %ebp
c010baad:	c3                   	ret    

c010baae <srand>:
/* *
 * srand - seed the random number generator with the given number
 * @seed:   the required seed number
 * */
void
srand(unsigned int seed) {
c010baae:	55                   	push   %ebp
c010baaf:	89 e5                	mov    %esp,%ebp
    next = seed;
c010bab1:	8b 45 08             	mov    0x8(%ebp),%eax
c010bab4:	ba 00 00 00 00       	mov    $0x0,%edx
c010bab9:	a3 20 fb 12 c0       	mov    %eax,0xc012fb20
c010babe:	89 15 24 fb 12 c0    	mov    %edx,0xc012fb24
}
c010bac4:	90                   	nop
c010bac5:	5d                   	pop    %ebp
c010bac6:	c3                   	ret    

c010bac7 <strlen>:
 * @s:      the input string
 *
 * The strlen() function returns the length of string @s.
 * */
size_t
strlen(const char *s) {
c010bac7:	55                   	push   %ebp
c010bac8:	89 e5                	mov    %esp,%ebp
c010baca:	83 ec 10             	sub    $0x10,%esp
    size_t cnt = 0;
c010bacd:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    while (*s ++ != '\0') {
c010bad4:	eb 03                	jmp    c010bad9 <strlen+0x12>
        cnt ++;
c010bad6:	ff 45 fc             	incl   -0x4(%ebp)
    while (*s ++ != '\0') {
c010bad9:	8b 45 08             	mov    0x8(%ebp),%eax
c010badc:	8d 50 01             	lea    0x1(%eax),%edx
c010badf:	89 55 08             	mov    %edx,0x8(%ebp)
c010bae2:	0f b6 00             	movzbl (%eax),%eax
c010bae5:	84 c0                	test   %al,%al
c010bae7:	75 ed                	jne    c010bad6 <strlen+0xf>
    }
    return cnt;
c010bae9:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c010baec:	89 ec                	mov    %ebp,%esp
c010baee:	5d                   	pop    %ebp
c010baef:	c3                   	ret    

c010baf0 <strnlen>:
 * The return value is strlen(s), if that is less than @len, or
 * @len if there is no '\0' character among the first @len characters
 * pointed by @s.
 * */
size_t
strnlen(const char *s, size_t len) {
c010baf0:	55                   	push   %ebp
c010baf1:	89 e5                	mov    %esp,%ebp
c010baf3:	83 ec 10             	sub    $0x10,%esp
    size_t cnt = 0;
c010baf6:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    while (cnt < len && *s ++ != '\0') {
c010bafd:	eb 03                	jmp    c010bb02 <strnlen+0x12>
        cnt ++;
c010baff:	ff 45 fc             	incl   -0x4(%ebp)
    while (cnt < len && *s ++ != '\0') {
c010bb02:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010bb05:	3b 45 0c             	cmp    0xc(%ebp),%eax
c010bb08:	73 10                	jae    c010bb1a <strnlen+0x2a>
c010bb0a:	8b 45 08             	mov    0x8(%ebp),%eax
c010bb0d:	8d 50 01             	lea    0x1(%eax),%edx
c010bb10:	89 55 08             	mov    %edx,0x8(%ebp)
c010bb13:	0f b6 00             	movzbl (%eax),%eax
c010bb16:	84 c0                	test   %al,%al
c010bb18:	75 e5                	jne    c010baff <strnlen+0xf>
    }
    return cnt;
c010bb1a:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c010bb1d:	89 ec                	mov    %ebp,%esp
c010bb1f:	5d                   	pop    %ebp
c010bb20:	c3                   	ret    

c010bb21 <strcpy>:
 * To avoid overflows, the size of array pointed by @dst should be long enough to
 * contain the same string as @src (including the terminating null character), and
 * should not overlap in memory with @src.
 * */
char *
strcpy(char *dst, const char *src) {
c010bb21:	55                   	push   %ebp
c010bb22:	89 e5                	mov    %esp,%ebp
c010bb24:	57                   	push   %edi
c010bb25:	56                   	push   %esi
c010bb26:	83 ec 20             	sub    $0x20,%esp
c010bb29:	8b 45 08             	mov    0x8(%ebp),%eax
c010bb2c:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010bb2f:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bb32:	89 45 f0             	mov    %eax,-0x10(%ebp)
#ifndef __HAVE_ARCH_STRCPY
#define __HAVE_ARCH_STRCPY
static inline char *
__strcpy(char *dst, const char *src) {
    int d0, d1, d2;
    asm volatile (
c010bb35:	8b 55 f0             	mov    -0x10(%ebp),%edx
c010bb38:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010bb3b:	89 d1                	mov    %edx,%ecx
c010bb3d:	89 c2                	mov    %eax,%edx
c010bb3f:	89 ce                	mov    %ecx,%esi
c010bb41:	89 d7                	mov    %edx,%edi
c010bb43:	ac                   	lods   %ds:(%esi),%al
c010bb44:	aa                   	stos   %al,%es:(%edi)
c010bb45:	84 c0                	test   %al,%al
c010bb47:	75 fa                	jne    c010bb43 <strcpy+0x22>
c010bb49:	89 fa                	mov    %edi,%edx
c010bb4b:	89 f1                	mov    %esi,%ecx
c010bb4d:	89 4d ec             	mov    %ecx,-0x14(%ebp)
c010bb50:	89 55 e8             	mov    %edx,-0x18(%ebp)
c010bb53:	89 45 e4             	mov    %eax,-0x1c(%ebp)
        "stosb;"
        "testb %%al, %%al;"
        "jne 1b;"
        : "=&S" (d0), "=&D" (d1), "=&a" (d2)
        : "0" (src), "1" (dst) : "memory");
    return dst;
c010bb56:	8b 45 f4             	mov    -0xc(%ebp),%eax
    char *p = dst;
    while ((*p ++ = *src ++) != '\0')
        /* nothing */;
    return dst;
#endif /* __HAVE_ARCH_STRCPY */
}
c010bb59:	83 c4 20             	add    $0x20,%esp
c010bb5c:	5e                   	pop    %esi
c010bb5d:	5f                   	pop    %edi
c010bb5e:	5d                   	pop    %ebp
c010bb5f:	c3                   	ret    

c010bb60 <strncpy>:
 * @len:    maximum number of characters to be copied from @src
 *
 * The return value is @dst
 * */
char *
strncpy(char *dst, const char *src, size_t len) {
c010bb60:	55                   	push   %ebp
c010bb61:	89 e5                	mov    %esp,%ebp
c010bb63:	83 ec 10             	sub    $0x10,%esp
    char *p = dst;
c010bb66:	8b 45 08             	mov    0x8(%ebp),%eax
c010bb69:	89 45 fc             	mov    %eax,-0x4(%ebp)
    while (len > 0) {
c010bb6c:	eb 1e                	jmp    c010bb8c <strncpy+0x2c>
        if ((*p = *src) != '\0') {
c010bb6e:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bb71:	0f b6 10             	movzbl (%eax),%edx
c010bb74:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010bb77:	88 10                	mov    %dl,(%eax)
c010bb79:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010bb7c:	0f b6 00             	movzbl (%eax),%eax
c010bb7f:	84 c0                	test   %al,%al
c010bb81:	74 03                	je     c010bb86 <strncpy+0x26>
            src ++;
c010bb83:	ff 45 0c             	incl   0xc(%ebp)
        }
        p ++, len --;
c010bb86:	ff 45 fc             	incl   -0x4(%ebp)
c010bb89:	ff 4d 10             	decl   0x10(%ebp)
    while (len > 0) {
c010bb8c:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010bb90:	75 dc                	jne    c010bb6e <strncpy+0xe>
    }
    return dst;
c010bb92:	8b 45 08             	mov    0x8(%ebp),%eax
}
c010bb95:	89 ec                	mov    %ebp,%esp
c010bb97:	5d                   	pop    %ebp
c010bb98:	c3                   	ret    

c010bb99 <strcmp>:
 * - A value greater than zero indicates that the first character that does
 *   not match has a greater value in @s1 than in @s2;
 * - And a value less than zero indicates the opposite.
 * */
int
strcmp(const char *s1, const char *s2) {
c010bb99:	55                   	push   %ebp
c010bb9a:	89 e5                	mov    %esp,%ebp
c010bb9c:	57                   	push   %edi
c010bb9d:	56                   	push   %esi
c010bb9e:	83 ec 20             	sub    $0x20,%esp
c010bba1:	8b 45 08             	mov    0x8(%ebp),%eax
c010bba4:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010bba7:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bbaa:	89 45 f0             	mov    %eax,-0x10(%ebp)
    asm volatile (
c010bbad:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010bbb0:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010bbb3:	89 d1                	mov    %edx,%ecx
c010bbb5:	89 c2                	mov    %eax,%edx
c010bbb7:	89 ce                	mov    %ecx,%esi
c010bbb9:	89 d7                	mov    %edx,%edi
c010bbbb:	ac                   	lods   %ds:(%esi),%al
c010bbbc:	ae                   	scas   %es:(%edi),%al
c010bbbd:	75 08                	jne    c010bbc7 <strcmp+0x2e>
c010bbbf:	84 c0                	test   %al,%al
c010bbc1:	75 f8                	jne    c010bbbb <strcmp+0x22>
c010bbc3:	31 c0                	xor    %eax,%eax
c010bbc5:	eb 04                	jmp    c010bbcb <strcmp+0x32>
c010bbc7:	19 c0                	sbb    %eax,%eax
c010bbc9:	0c 01                	or     $0x1,%al
c010bbcb:	89 fa                	mov    %edi,%edx
c010bbcd:	89 f1                	mov    %esi,%ecx
c010bbcf:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010bbd2:	89 4d e8             	mov    %ecx,-0x18(%ebp)
c010bbd5:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    return ret;
c010bbd8:	8b 45 ec             	mov    -0x14(%ebp),%eax
    while (*s1 != '\0' && *s1 == *s2) {
        s1 ++, s2 ++;
    }
    return (int)((unsigned char)*s1 - (unsigned char)*s2);
#endif /* __HAVE_ARCH_STRCMP */
}
c010bbdb:	83 c4 20             	add    $0x20,%esp
c010bbde:	5e                   	pop    %esi
c010bbdf:	5f                   	pop    %edi
c010bbe0:	5d                   	pop    %ebp
c010bbe1:	c3                   	ret    

c010bbe2 <strncmp>:
 * they are equal to each other, it continues with the following pairs until
 * the characters differ, until a terminating null-character is reached, or
 * until @n characters match in both strings, whichever happens first.
 * */
int
strncmp(const char *s1, const char *s2, size_t n) {
c010bbe2:	55                   	push   %ebp
c010bbe3:	89 e5                	mov    %esp,%ebp
    while (n > 0 && *s1 != '\0' && *s1 == *s2) {
c010bbe5:	eb 09                	jmp    c010bbf0 <strncmp+0xe>
        n --, s1 ++, s2 ++;
c010bbe7:	ff 4d 10             	decl   0x10(%ebp)
c010bbea:	ff 45 08             	incl   0x8(%ebp)
c010bbed:	ff 45 0c             	incl   0xc(%ebp)
    while (n > 0 && *s1 != '\0' && *s1 == *s2) {
c010bbf0:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010bbf4:	74 1a                	je     c010bc10 <strncmp+0x2e>
c010bbf6:	8b 45 08             	mov    0x8(%ebp),%eax
c010bbf9:	0f b6 00             	movzbl (%eax),%eax
c010bbfc:	84 c0                	test   %al,%al
c010bbfe:	74 10                	je     c010bc10 <strncmp+0x2e>
c010bc00:	8b 45 08             	mov    0x8(%ebp),%eax
c010bc03:	0f b6 10             	movzbl (%eax),%edx
c010bc06:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bc09:	0f b6 00             	movzbl (%eax),%eax
c010bc0c:	38 c2                	cmp    %al,%dl
c010bc0e:	74 d7                	je     c010bbe7 <strncmp+0x5>
    }
    return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2);
c010bc10:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010bc14:	74 18                	je     c010bc2e <strncmp+0x4c>
c010bc16:	8b 45 08             	mov    0x8(%ebp),%eax
c010bc19:	0f b6 00             	movzbl (%eax),%eax
c010bc1c:	0f b6 d0             	movzbl %al,%edx
c010bc1f:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bc22:	0f b6 00             	movzbl (%eax),%eax
c010bc25:	0f b6 c8             	movzbl %al,%ecx
c010bc28:	89 d0                	mov    %edx,%eax
c010bc2a:	29 c8                	sub    %ecx,%eax
c010bc2c:	eb 05                	jmp    c010bc33 <strncmp+0x51>
c010bc2e:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010bc33:	5d                   	pop    %ebp
c010bc34:	c3                   	ret    

c010bc35 <strchr>:
 *
 * The strchr() function returns a pointer to the first occurrence of
 * character in @s. If the value is not found, the function returns 'NULL'.
 * */
char *
strchr(const char *s, char c) {
c010bc35:	55                   	push   %ebp
c010bc36:	89 e5                	mov    %esp,%ebp
c010bc38:	83 ec 04             	sub    $0x4,%esp
c010bc3b:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bc3e:	88 45 fc             	mov    %al,-0x4(%ebp)
    while (*s != '\0') {
c010bc41:	eb 13                	jmp    c010bc56 <strchr+0x21>
        if (*s == c) {
c010bc43:	8b 45 08             	mov    0x8(%ebp),%eax
c010bc46:	0f b6 00             	movzbl (%eax),%eax
c010bc49:	38 45 fc             	cmp    %al,-0x4(%ebp)
c010bc4c:	75 05                	jne    c010bc53 <strchr+0x1e>
            return (char *)s;
c010bc4e:	8b 45 08             	mov    0x8(%ebp),%eax
c010bc51:	eb 12                	jmp    c010bc65 <strchr+0x30>
        }
        s ++;
c010bc53:	ff 45 08             	incl   0x8(%ebp)
    while (*s != '\0') {
c010bc56:	8b 45 08             	mov    0x8(%ebp),%eax
c010bc59:	0f b6 00             	movzbl (%eax),%eax
c010bc5c:	84 c0                	test   %al,%al
c010bc5e:	75 e3                	jne    c010bc43 <strchr+0xe>
    }
    return NULL;
c010bc60:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010bc65:	89 ec                	mov    %ebp,%esp
c010bc67:	5d                   	pop    %ebp
c010bc68:	c3                   	ret    

c010bc69 <strfind>:
 * The strfind() function is like strchr() except that if @c is
 * not found in @s, then it returns a pointer to the null byte at the
 * end of @s, rather than 'NULL'.
 * */
char *
strfind(const char *s, char c) {
c010bc69:	55                   	push   %ebp
c010bc6a:	89 e5                	mov    %esp,%ebp
c010bc6c:	83 ec 04             	sub    $0x4,%esp
c010bc6f:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bc72:	88 45 fc             	mov    %al,-0x4(%ebp)
    while (*s != '\0') {
c010bc75:	eb 0e                	jmp    c010bc85 <strfind+0x1c>
        if (*s == c) {
c010bc77:	8b 45 08             	mov    0x8(%ebp),%eax
c010bc7a:	0f b6 00             	movzbl (%eax),%eax
c010bc7d:	38 45 fc             	cmp    %al,-0x4(%ebp)
c010bc80:	74 0f                	je     c010bc91 <strfind+0x28>
            break;
        }
        s ++;
c010bc82:	ff 45 08             	incl   0x8(%ebp)
    while (*s != '\0') {
c010bc85:	8b 45 08             	mov    0x8(%ebp),%eax
c010bc88:	0f b6 00             	movzbl (%eax),%eax
c010bc8b:	84 c0                	test   %al,%al
c010bc8d:	75 e8                	jne    c010bc77 <strfind+0xe>
c010bc8f:	eb 01                	jmp    c010bc92 <strfind+0x29>
            break;
c010bc91:	90                   	nop
    }
    return (char *)s;
c010bc92:	8b 45 08             	mov    0x8(%ebp),%eax
}
c010bc95:	89 ec                	mov    %ebp,%esp
c010bc97:	5d                   	pop    %ebp
c010bc98:	c3                   	ret    

c010bc99 <strtol>:
 * an optional "0x" or "0X" prefix.
 *
 * The strtol() function returns the converted integral number as a long int value.
 * */
long
strtol(const char *s, char **endptr, int base) {
c010bc99:	55                   	push   %ebp
c010bc9a:	89 e5                	mov    %esp,%ebp
c010bc9c:	83 ec 10             	sub    $0x10,%esp
    int neg = 0;
c010bc9f:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    long val = 0;
c010bca6:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%ebp)

    // gobble initial whitespace
    while (*s == ' ' || *s == '\t') {
c010bcad:	eb 03                	jmp    c010bcb2 <strtol+0x19>
        s ++;
c010bcaf:	ff 45 08             	incl   0x8(%ebp)
    while (*s == ' ' || *s == '\t') {
c010bcb2:	8b 45 08             	mov    0x8(%ebp),%eax
c010bcb5:	0f b6 00             	movzbl (%eax),%eax
c010bcb8:	3c 20                	cmp    $0x20,%al
c010bcba:	74 f3                	je     c010bcaf <strtol+0x16>
c010bcbc:	8b 45 08             	mov    0x8(%ebp),%eax
c010bcbf:	0f b6 00             	movzbl (%eax),%eax
c010bcc2:	3c 09                	cmp    $0x9,%al
c010bcc4:	74 e9                	je     c010bcaf <strtol+0x16>
    }

    // plus/minus sign
    if (*s == '+') {
c010bcc6:	8b 45 08             	mov    0x8(%ebp),%eax
c010bcc9:	0f b6 00             	movzbl (%eax),%eax
c010bccc:	3c 2b                	cmp    $0x2b,%al
c010bcce:	75 05                	jne    c010bcd5 <strtol+0x3c>
        s ++;
c010bcd0:	ff 45 08             	incl   0x8(%ebp)
c010bcd3:	eb 14                	jmp    c010bce9 <strtol+0x50>
    }
    else if (*s == '-') {
c010bcd5:	8b 45 08             	mov    0x8(%ebp),%eax
c010bcd8:	0f b6 00             	movzbl (%eax),%eax
c010bcdb:	3c 2d                	cmp    $0x2d,%al
c010bcdd:	75 0a                	jne    c010bce9 <strtol+0x50>
        s ++, neg = 1;
c010bcdf:	ff 45 08             	incl   0x8(%ebp)
c010bce2:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%ebp)
    }

    // hex or octal base prefix
    if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) {
c010bce9:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010bced:	74 06                	je     c010bcf5 <strtol+0x5c>
c010bcef:	83 7d 10 10          	cmpl   $0x10,0x10(%ebp)
c010bcf3:	75 22                	jne    c010bd17 <strtol+0x7e>
c010bcf5:	8b 45 08             	mov    0x8(%ebp),%eax
c010bcf8:	0f b6 00             	movzbl (%eax),%eax
c010bcfb:	3c 30                	cmp    $0x30,%al
c010bcfd:	75 18                	jne    c010bd17 <strtol+0x7e>
c010bcff:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd02:	40                   	inc    %eax
c010bd03:	0f b6 00             	movzbl (%eax),%eax
c010bd06:	3c 78                	cmp    $0x78,%al
c010bd08:	75 0d                	jne    c010bd17 <strtol+0x7e>
        s += 2, base = 16;
c010bd0a:	83 45 08 02          	addl   $0x2,0x8(%ebp)
c010bd0e:	c7 45 10 10 00 00 00 	movl   $0x10,0x10(%ebp)
c010bd15:	eb 29                	jmp    c010bd40 <strtol+0xa7>
    }
    else if (base == 0 && s[0] == '0') {
c010bd17:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010bd1b:	75 16                	jne    c010bd33 <strtol+0x9a>
c010bd1d:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd20:	0f b6 00             	movzbl (%eax),%eax
c010bd23:	3c 30                	cmp    $0x30,%al
c010bd25:	75 0c                	jne    c010bd33 <strtol+0x9a>
        s ++, base = 8;
c010bd27:	ff 45 08             	incl   0x8(%ebp)
c010bd2a:	c7 45 10 08 00 00 00 	movl   $0x8,0x10(%ebp)
c010bd31:	eb 0d                	jmp    c010bd40 <strtol+0xa7>
    }
    else if (base == 0) {
c010bd33:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010bd37:	75 07                	jne    c010bd40 <strtol+0xa7>
        base = 10;
c010bd39:	c7 45 10 0a 00 00 00 	movl   $0xa,0x10(%ebp)

    // digits
    while (1) {
        int dig;

        if (*s >= '0' && *s <= '9') {
c010bd40:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd43:	0f b6 00             	movzbl (%eax),%eax
c010bd46:	3c 2f                	cmp    $0x2f,%al
c010bd48:	7e 1b                	jle    c010bd65 <strtol+0xcc>
c010bd4a:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd4d:	0f b6 00             	movzbl (%eax),%eax
c010bd50:	3c 39                	cmp    $0x39,%al
c010bd52:	7f 11                	jg     c010bd65 <strtol+0xcc>
            dig = *s - '0';
c010bd54:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd57:	0f b6 00             	movzbl (%eax),%eax
c010bd5a:	0f be c0             	movsbl %al,%eax
c010bd5d:	83 e8 30             	sub    $0x30,%eax
c010bd60:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010bd63:	eb 48                	jmp    c010bdad <strtol+0x114>
        }
        else if (*s >= 'a' && *s <= 'z') {
c010bd65:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd68:	0f b6 00             	movzbl (%eax),%eax
c010bd6b:	3c 60                	cmp    $0x60,%al
c010bd6d:	7e 1b                	jle    c010bd8a <strtol+0xf1>
c010bd6f:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd72:	0f b6 00             	movzbl (%eax),%eax
c010bd75:	3c 7a                	cmp    $0x7a,%al
c010bd77:	7f 11                	jg     c010bd8a <strtol+0xf1>
            dig = *s - 'a' + 10;
c010bd79:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd7c:	0f b6 00             	movzbl (%eax),%eax
c010bd7f:	0f be c0             	movsbl %al,%eax
c010bd82:	83 e8 57             	sub    $0x57,%eax
c010bd85:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010bd88:	eb 23                	jmp    c010bdad <strtol+0x114>
        }
        else if (*s >= 'A' && *s <= 'Z') {
c010bd8a:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd8d:	0f b6 00             	movzbl (%eax),%eax
c010bd90:	3c 40                	cmp    $0x40,%al
c010bd92:	7e 3b                	jle    c010bdcf <strtol+0x136>
c010bd94:	8b 45 08             	mov    0x8(%ebp),%eax
c010bd97:	0f b6 00             	movzbl (%eax),%eax
c010bd9a:	3c 5a                	cmp    $0x5a,%al
c010bd9c:	7f 31                	jg     c010bdcf <strtol+0x136>
            dig = *s - 'A' + 10;
c010bd9e:	8b 45 08             	mov    0x8(%ebp),%eax
c010bda1:	0f b6 00             	movzbl (%eax),%eax
c010bda4:	0f be c0             	movsbl %al,%eax
c010bda7:	83 e8 37             	sub    $0x37,%eax
c010bdaa:	89 45 f4             	mov    %eax,-0xc(%ebp)
        }
        else {
            break;
        }
        if (dig >= base) {
c010bdad:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010bdb0:	3b 45 10             	cmp    0x10(%ebp),%eax
c010bdb3:	7d 19                	jge    c010bdce <strtol+0x135>
            break;
        }
        s ++, val = (val * base) + dig;
c010bdb5:	ff 45 08             	incl   0x8(%ebp)
c010bdb8:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010bdbb:	0f af 45 10          	imul   0x10(%ebp),%eax
c010bdbf:	89 c2                	mov    %eax,%edx
c010bdc1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010bdc4:	01 d0                	add    %edx,%eax
c010bdc6:	89 45 f8             	mov    %eax,-0x8(%ebp)
    while (1) {
c010bdc9:	e9 72 ff ff ff       	jmp    c010bd40 <strtol+0xa7>
            break;
c010bdce:	90                   	nop
        // we don't properly detect overflow!
    }

    if (endptr) {
c010bdcf:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010bdd3:	74 08                	je     c010bddd <strtol+0x144>
        *endptr = (char *) s;
c010bdd5:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bdd8:	8b 55 08             	mov    0x8(%ebp),%edx
c010bddb:	89 10                	mov    %edx,(%eax)
    }
    return (neg ? -val : val);
c010bddd:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c010bde1:	74 07                	je     c010bdea <strtol+0x151>
c010bde3:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010bde6:	f7 d8                	neg    %eax
c010bde8:	eb 03                	jmp    c010bded <strtol+0x154>
c010bdea:	8b 45 f8             	mov    -0x8(%ebp),%eax
}
c010bded:	89 ec                	mov    %ebp,%esp
c010bdef:	5d                   	pop    %ebp
c010bdf0:	c3                   	ret    

c010bdf1 <memset>:
 * @n:      number of bytes to be set to the value
 *
 * The memset() function returns @s.
 * */
void *
memset(void *s, char c, size_t n) {
c010bdf1:	55                   	push   %ebp
c010bdf2:	89 e5                	mov    %esp,%ebp
c010bdf4:	83 ec 28             	sub    $0x28,%esp
c010bdf7:	89 7d fc             	mov    %edi,-0x4(%ebp)
c010bdfa:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bdfd:	88 45 d8             	mov    %al,-0x28(%ebp)
#ifdef __HAVE_ARCH_MEMSET
    return __memset(s, c, n);
c010be00:	0f be 55 d8          	movsbl -0x28(%ebp),%edx
c010be04:	8b 45 08             	mov    0x8(%ebp),%eax
c010be07:	89 45 f8             	mov    %eax,-0x8(%ebp)
c010be0a:	88 55 f7             	mov    %dl,-0x9(%ebp)
c010be0d:	8b 45 10             	mov    0x10(%ebp),%eax
c010be10:	89 45 f0             	mov    %eax,-0x10(%ebp)
#ifndef __HAVE_ARCH_MEMSET
#define __HAVE_ARCH_MEMSET
static inline void *
__memset(void *s, char c, size_t n) {
    int d0, d1;
    asm volatile (
c010be13:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c010be16:	0f b6 45 f7          	movzbl -0x9(%ebp),%eax
c010be1a:	8b 55 f8             	mov    -0x8(%ebp),%edx
c010be1d:	89 d7                	mov    %edx,%edi
c010be1f:	f3 aa                	rep stos %al,%es:(%edi)
c010be21:	89 fa                	mov    %edi,%edx
c010be23:	89 4d ec             	mov    %ecx,-0x14(%ebp)
c010be26:	89 55 e8             	mov    %edx,-0x18(%ebp)
        "rep; stosb;"
        : "=&c" (d0), "=&D" (d1)
        : "0" (n), "a" (c), "1" (s)
        : "memory");
    return s;
c010be29:	8b 45 f8             	mov    -0x8(%ebp),%eax
    while (n -- > 0) {
        *p ++ = c;
    }
    return s;
#endif /* __HAVE_ARCH_MEMSET */
}
c010be2c:	8b 7d fc             	mov    -0x4(%ebp),%edi
c010be2f:	89 ec                	mov    %ebp,%esp
c010be31:	5d                   	pop    %ebp
c010be32:	c3                   	ret    

c010be33 <memmove>:
 * @n:      number of bytes to copy
 *
 * The memmove() function returns @dst.
 * */
void *
memmove(void *dst, const void *src, size_t n) {
c010be33:	55                   	push   %ebp
c010be34:	89 e5                	mov    %esp,%ebp
c010be36:	57                   	push   %edi
c010be37:	56                   	push   %esi
c010be38:	53                   	push   %ebx
c010be39:	83 ec 30             	sub    $0x30,%esp
c010be3c:	8b 45 08             	mov    0x8(%ebp),%eax
c010be3f:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010be42:	8b 45 0c             	mov    0xc(%ebp),%eax
c010be45:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010be48:	8b 45 10             	mov    0x10(%ebp),%eax
c010be4b:	89 45 e8             	mov    %eax,-0x18(%ebp)

#ifndef __HAVE_ARCH_MEMMOVE
#define __HAVE_ARCH_MEMMOVE
static inline void *
__memmove(void *dst, const void *src, size_t n) {
    if (dst < src) {
c010be4e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010be51:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c010be54:	73 42                	jae    c010be98 <memmove+0x65>
c010be56:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010be59:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c010be5c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010be5f:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010be62:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010be65:	89 45 dc             	mov    %eax,-0x24(%ebp)
        "andl $3, %%ecx;"
        "jz 1f;"
        "rep; movsb;"
        "1:"
        : "=&c" (d0), "=&D" (d1), "=&S" (d2)
        : "0" (n / 4), "g" (n), "1" (dst), "2" (src)
c010be68:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010be6b:	c1 e8 02             	shr    $0x2,%eax
c010be6e:	89 c1                	mov    %eax,%ecx
    asm volatile (
c010be70:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010be73:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010be76:	89 d7                	mov    %edx,%edi
c010be78:	89 c6                	mov    %eax,%esi
c010be7a:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
c010be7c:	8b 4d dc             	mov    -0x24(%ebp),%ecx
c010be7f:	83 e1 03             	and    $0x3,%ecx
c010be82:	74 02                	je     c010be86 <memmove+0x53>
c010be84:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c010be86:	89 f0                	mov    %esi,%eax
c010be88:	89 fa                	mov    %edi,%edx
c010be8a:	89 4d d8             	mov    %ecx,-0x28(%ebp)
c010be8d:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c010be90:	89 45 d0             	mov    %eax,-0x30(%ebp)
        : "memory");
    return dst;
c010be93:	8b 45 e4             	mov    -0x1c(%ebp),%eax
        return __memcpy(dst, src, n);
c010be96:	eb 36                	jmp    c010bece <memmove+0x9b>
        : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst)
c010be98:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010be9b:	8d 50 ff             	lea    -0x1(%eax),%edx
c010be9e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010bea1:	01 c2                	add    %eax,%edx
c010bea3:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010bea6:	8d 48 ff             	lea    -0x1(%eax),%ecx
c010bea9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010beac:	8d 1c 01             	lea    (%ecx,%eax,1),%ebx
    asm volatile (
c010beaf:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010beb2:	89 c1                	mov    %eax,%ecx
c010beb4:	89 d8                	mov    %ebx,%eax
c010beb6:	89 d6                	mov    %edx,%esi
c010beb8:	89 c7                	mov    %eax,%edi
c010beba:	fd                   	std    
c010bebb:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c010bebd:	fc                   	cld    
c010bebe:	89 f8                	mov    %edi,%eax
c010bec0:	89 f2                	mov    %esi,%edx
c010bec2:	89 4d cc             	mov    %ecx,-0x34(%ebp)
c010bec5:	89 55 c8             	mov    %edx,-0x38(%ebp)
c010bec8:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    return dst;
c010becb:	8b 45 f0             	mov    -0x10(%ebp),%eax
            *d ++ = *s ++;
        }
    }
    return dst;
#endif /* __HAVE_ARCH_MEMMOVE */
}
c010bece:	83 c4 30             	add    $0x30,%esp
c010bed1:	5b                   	pop    %ebx
c010bed2:	5e                   	pop    %esi
c010bed3:	5f                   	pop    %edi
c010bed4:	5d                   	pop    %ebp
c010bed5:	c3                   	ret    

c010bed6 <memcpy>:
 * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed
 * by both @src and @dst, should be at least @n bytes, and should not overlap
 * (for overlapping memory area, memmove is a safer approach).
 * */
void *
memcpy(void *dst, const void *src, size_t n) {
c010bed6:	55                   	push   %ebp
c010bed7:	89 e5                	mov    %esp,%ebp
c010bed9:	57                   	push   %edi
c010beda:	56                   	push   %esi
c010bedb:	83 ec 20             	sub    $0x20,%esp
c010bede:	8b 45 08             	mov    0x8(%ebp),%eax
c010bee1:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010bee4:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bee7:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010beea:	8b 45 10             	mov    0x10(%ebp),%eax
c010beed:	89 45 ec             	mov    %eax,-0x14(%ebp)
        : "0" (n / 4), "g" (n), "1" (dst), "2" (src)
c010bef0:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010bef3:	c1 e8 02             	shr    $0x2,%eax
c010bef6:	89 c1                	mov    %eax,%ecx
    asm volatile (
c010bef8:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010befb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010befe:	89 d7                	mov    %edx,%edi
c010bf00:	89 c6                	mov    %eax,%esi
c010bf02:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
c010bf04:	8b 4d ec             	mov    -0x14(%ebp),%ecx
c010bf07:	83 e1 03             	and    $0x3,%ecx
c010bf0a:	74 02                	je     c010bf0e <memcpy+0x38>
c010bf0c:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c010bf0e:	89 f0                	mov    %esi,%eax
c010bf10:	89 fa                	mov    %edi,%edx
c010bf12:	89 4d e8             	mov    %ecx,-0x18(%ebp)
c010bf15:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c010bf18:	89 45 e0             	mov    %eax,-0x20(%ebp)
    return dst;
c010bf1b:	8b 45 f4             	mov    -0xc(%ebp),%eax
    while (n -- > 0) {
        *d ++ = *s ++;
    }
    return dst;
#endif /* __HAVE_ARCH_MEMCPY */
}
c010bf1e:	83 c4 20             	add    $0x20,%esp
c010bf21:	5e                   	pop    %esi
c010bf22:	5f                   	pop    %edi
c010bf23:	5d                   	pop    %ebp
c010bf24:	c3                   	ret    

c010bf25 <memcmp>:
 *   match in both memory blocks has a greater value in @v1 than in @v2
 *   as if evaluated as unsigned char values;
 * - And a value less than zero indicates the opposite.
 * */
int
memcmp(const void *v1, const void *v2, size_t n) {
c010bf25:	55                   	push   %ebp
c010bf26:	89 e5                	mov    %esp,%ebp
c010bf28:	83 ec 10             	sub    $0x10,%esp
    const char *s1 = (const char *)v1;
c010bf2b:	8b 45 08             	mov    0x8(%ebp),%eax
c010bf2e:	89 45 fc             	mov    %eax,-0x4(%ebp)
    const char *s2 = (const char *)v2;
c010bf31:	8b 45 0c             	mov    0xc(%ebp),%eax
c010bf34:	89 45 f8             	mov    %eax,-0x8(%ebp)
    while (n -- > 0) {
c010bf37:	eb 2e                	jmp    c010bf67 <memcmp+0x42>
        if (*s1 != *s2) {
c010bf39:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010bf3c:	0f b6 10             	movzbl (%eax),%edx
c010bf3f:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010bf42:	0f b6 00             	movzbl (%eax),%eax
c010bf45:	38 c2                	cmp    %al,%dl
c010bf47:	74 18                	je     c010bf61 <memcmp+0x3c>
            return (int)((unsigned char)*s1 - (unsigned char)*s2);
c010bf49:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010bf4c:	0f b6 00             	movzbl (%eax),%eax
c010bf4f:	0f b6 d0             	movzbl %al,%edx
c010bf52:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010bf55:	0f b6 00             	movzbl (%eax),%eax
c010bf58:	0f b6 c8             	movzbl %al,%ecx
c010bf5b:	89 d0                	mov    %edx,%eax
c010bf5d:	29 c8                	sub    %ecx,%eax
c010bf5f:	eb 18                	jmp    c010bf79 <memcmp+0x54>
        }
        s1 ++, s2 ++;
c010bf61:	ff 45 fc             	incl   -0x4(%ebp)
c010bf64:	ff 45 f8             	incl   -0x8(%ebp)
    while (n -- > 0) {
c010bf67:	8b 45 10             	mov    0x10(%ebp),%eax
c010bf6a:	8d 50 ff             	lea    -0x1(%eax),%edx
c010bf6d:	89 55 10             	mov    %edx,0x10(%ebp)
c010bf70:	85 c0                	test   %eax,%eax
c010bf72:	75 c5                	jne    c010bf39 <memcmp+0x14>
    }
    return 0;
c010bf74:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010bf79:	89 ec                	mov    %ebp,%esp
c010bf7b:	5d                   	pop    %ebp
c010bf7c:	c3                   	ret    
